Commit dab2f932 authored by Nick Thomas's avatar Nick Thomas

Merge branch 'feature/migrate-send-diff-patch-to-gitaly' into 'master'

Migrate Send{Diff,Patch} to Gitaly

Closes gitaly#622 and gitaly#612

See merge request gitlab-org/gitlab-workhorse!200
parents 17bd7545 fe1def6e
...@@ -340,6 +340,46 @@ func TestGetBlobProxiedToGitalySuccessfully(t *testing.T) { ...@@ -340,6 +340,46 @@ func TestGetBlobProxiedToGitalySuccessfully(t *testing.T) {
testhelper.AssertResponseHeader(t, resp, "Content-Length", strconv.Itoa(blobLength)) testhelper.AssertResponseHeader(t, resp, "Content-Length", strconv.Itoa(blobLength))
} }
func TestGetDiffProxiedToGitalySuccessfully(t *testing.T) {
gitalyServer, socketPath := startGitalyServer(t, codes.OK)
defer gitalyServer.Stop()
gitalyAddress := "unix://" + socketPath
repoStorage := "default"
rightCommit := "e395f646b1499e8e0279445fc99a0596a65fab7e"
leftCommit := "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"
repoRelativePath := "foo/bar.git"
jsonParams := fmt.Sprintf(`{"GitalyServer":{"Address":"%s","Token":""},"RawDiffRequest":"{\"repository\":{\"storageName\":\"%s\",\"relativePath\":\"%s\"},\"rightCommitId\":\"%s\",\"leftCommitId\":\"%s\"}"}`,
gitalyAddress, repoStorage, repoRelativePath, leftCommit, rightCommit)
expectedBody := testhelper.GitalyGetDiffResponseMock
resp, body, err := doSendDataRequest("/something", "git-diff", jsonParams)
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode, "GET %q: status code", resp.Request.URL)
assert.Equal(t, expectedBody, string(body), "GET %q: response body", resp.Request.URL)
}
func TestGetPatchProxiedToGitalySuccessfully(t *testing.T) {
gitalyServer, socketPath := startGitalyServer(t, codes.OK)
defer gitalyServer.Stop()
gitalyAddress := "unix://" + socketPath
repoStorage := "default"
rightCommit := "e395f646b1499e8e0279445fc99a0596a65fab7e"
leftCommit := "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"
repoRelativePath := "foo/bar.git"
jsonParams := fmt.Sprintf(`{"GitalyServer":{"Address":"%s","Token":""},"RawPatchRequest":"{\"repository\":{\"storageName\":\"%s\",\"relativePath\":\"%s\"},\"rightCommitId\":\"%s\",\"leftCommitId\":\"%s\"}"}`,
gitalyAddress, repoStorage, repoRelativePath, leftCommit, rightCommit)
expectedBody := testhelper.GitalyGetPatchResponseMock
resp, body, err := doSendDataRequest("/something", "git-format-patch", jsonParams)
require.NoError(t, err)
assert.Equal(t, 200, resp.StatusCode, "GET %q: status code", resp.Request.URL)
assert.Equal(t, expectedBody, string(body), "GET %q: response body", resp.Request.URL)
}
func TestGetBlobProxiedToGitalyInterruptedStream(t *testing.T) { func TestGetBlobProxiedToGitalyInterruptedStream(t *testing.T) {
gitalyServer, socketPath := startGitalyServer(t, codes.OK) gitalyServer, socketPath := startGitalyServer(t, codes.OK)
defer gitalyServer.Stop() defer gitalyServer.Stop()
...@@ -427,6 +467,70 @@ func TestGetArchiveProxiedToGitalyInterruptedStream(t *testing.T) { ...@@ -427,6 +467,70 @@ func TestGetArchiveProxiedToGitalyInterruptedStream(t *testing.T) {
} }
} }
func TestGetDiffProxiedToGitalyInterruptedStream(t *testing.T) {
gitalyServer, socketPath := startGitalyServer(t, codes.OK)
defer gitalyServer.Stop()
gitalyAddress := "unix://" + socketPath
repoStorage := "default"
rightCommit := "e395f646b1499e8e0279445fc99a0596a65fab7e"
leftCommit := "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"
repoRelativePath := "foo/bar.git"
jsonParams := fmt.Sprintf(`{"GitalyServer":{"Address":"%s","Token":""},"RawDiffRequest":"{\"repository\":{\"storageName\":\"%s\",\"relativePath\":\"%s\"},\"rightCommitId\":\"%s\",\"leftCommitId\":\"%s\"}"}`,
gitalyAddress, repoStorage, repoRelativePath, leftCommit, rightCommit)
resp, _, err := doSendDataRequest("/something", "git-diff", jsonParams)
require.NoError(t, err)
// This causes the server stream to be interrupted instead of consumed entirely.
resp.Body.Close()
done := make(chan struct{})
go func() {
gitalyServer.WaitGroup.Wait()
close(done)
}()
select {
case <-done:
return
case <-time.After(10 * time.Second):
t.Fatal("time out waiting for gitaly handler to return")
}
}
func TestGetPatchProxiedToGitalyInterruptedStream(t *testing.T) {
gitalyServer, socketPath := startGitalyServer(t, codes.OK)
defer gitalyServer.Stop()
gitalyAddress := "unix://" + socketPath
repoStorage := "default"
rightCommit := "e395f646b1499e8e0279445fc99a0596a65fab7e"
leftCommit := "8a0f2ee90d940bfb0ba1e14e8214b0649056e4ab"
repoRelativePath := "foo/bar.git"
jsonParams := fmt.Sprintf(`{"GitalyServer":{"Address":"%s","Token":""},"RawPatchRequest":"{\"repository\":{\"storageName\":\"%s\",\"relativePath\":\"%s\"},\"rightCommitId\":\"%s\",\"leftCommitId\":\"%s\"}"}`,
gitalyAddress, repoStorage, repoRelativePath, leftCommit, rightCommit)
resp, _, err := doSendDataRequest("/something", "git-format-patch", jsonParams)
require.NoError(t, err)
// This causes the server stream to be interrupted instead of consumed entirely.
resp.Body.Close()
done := make(chan struct{})
go func() {
gitalyServer.WaitGroup.Wait()
close(done)
}()
select {
case <-done:
return
case <-time.After(10 * time.Second):
t.Fatal("time out waiting for gitaly handler to return")
}
}
type combinedServer struct { type combinedServer struct {
*grpc.Server *grpc.Server
*testhelper.GitalyTestServer *testhelper.GitalyTestServer
...@@ -445,6 +549,7 @@ func startGitalyServer(t *testing.T, finalMessageCode codes.Code) (*combinedServ ...@@ -445,6 +549,7 @@ func startGitalyServer(t *testing.T, finalMessageCode codes.Code) (*combinedServ
pb.RegisterSmartHTTPServiceServer(server, gitalyServer) pb.RegisterSmartHTTPServiceServer(server, gitalyServer)
pb.RegisterBlobServiceServer(server, gitalyServer) pb.RegisterBlobServiceServer(server, gitalyServer)
pb.RegisterRepositoryServiceServer(server, gitalyServer) pb.RegisterRepositoryServiceServer(server, gitalyServer)
pb.RegisterDiffServiceServer(server, gitalyServer)
go server.Serve(listener) go server.Serve(listener)
......
...@@ -6,8 +6,13 @@ import ( ...@@ -6,8 +6,13 @@ import (
"log" "log"
"net/http" "net/http"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/gitaly"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/helper" "gitlab.com/gitlab-org/gitlab-workhorse/internal/helper"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/senddata" "gitlab.com/gitlab-org/gitlab-workhorse/internal/senddata"
pb "gitlab.com/gitlab-org/gitaly-proto/go"
"github.com/golang/protobuf/jsonpb"
) )
type diff struct{ senddata.Prefix } type diff struct{ senddata.Prefix }
...@@ -15,6 +20,8 @@ type diffParams struct { ...@@ -15,6 +20,8 @@ type diffParams struct {
RepoPath string RepoPath string
ShaFrom string ShaFrom string
ShaTo string ShaTo string
GitalyServer gitaly.Server
RawDiffRequest string
} }
var SendDiff = &diff{"git-diff:"} var SendDiff = &diff{"git-diff:"}
...@@ -26,6 +33,33 @@ func (d *diff) Inject(w http.ResponseWriter, r *http.Request, sendData string) { ...@@ -26,6 +33,33 @@ func (d *diff) Inject(w http.ResponseWriter, r *http.Request, sendData string) {
return return
} }
if params.GitalyServer.Address != "" {
handleSendDiffWithGitaly(w, r, &params)
} else {
handleSendDiffLocally(w, r, &params)
}
}
func handleSendDiffWithGitaly(w http.ResponseWriter, r *http.Request, params *diffParams) {
request := &pb.RawDiffRequest{}
if err := jsonpb.UnmarshalString(params.RawDiffRequest, request); err != nil {
helper.Fail500(w, r, fmt.Errorf("diff.RawDiff: %v", err))
}
diffClient, err := gitaly.NewDiffClient(params.GitalyServer)
if err != nil {
helper.Fail500(w, r, fmt.Errorf("diff.RawDiff: %v", err))
}
if err := diffClient.SendRawDiff(r.Context(), w, request); err != nil {
helper.LogError(
r,
&copyError{fmt.Errorf("diff.RawDiff: request=%v, err=%v", request, err)},
)
}
}
func handleSendDiffLocally(w http.ResponseWriter, r *http.Request, params *diffParams) {
log.Printf("SendDiff: sending diff between %q and %q for %q", params.ShaFrom, params.ShaTo, r.URL.Path) log.Printf("SendDiff: sending diff between %q and %q for %q", params.ShaFrom, params.ShaTo, r.URL.Path)
gitDiffCmd := gitCommand("git", "--git-dir="+params.RepoPath, "diff", params.ShaFrom, params.ShaTo) gitDiffCmd := gitCommand("git", "--git-dir="+params.RepoPath, "diff", params.ShaFrom, params.ShaTo)
......
...@@ -6,8 +6,13 @@ import ( ...@@ -6,8 +6,13 @@ import (
"log" "log"
"net/http" "net/http"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/gitaly"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/helper" "gitlab.com/gitlab-org/gitlab-workhorse/internal/helper"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/senddata" "gitlab.com/gitlab-org/gitlab-workhorse/internal/senddata"
pb "gitlab.com/gitlab-org/gitaly-proto/go"
"github.com/golang/protobuf/jsonpb"
) )
type patch struct{ senddata.Prefix } type patch struct{ senddata.Prefix }
...@@ -15,6 +20,8 @@ type patchParams struct { ...@@ -15,6 +20,8 @@ type patchParams struct {
RepoPath string RepoPath string
ShaFrom string ShaFrom string
ShaTo string ShaTo string
GitalyServer gitaly.Server
RawPatchRequest string
} }
var SendPatch = &patch{"git-format-patch:"} var SendPatch = &patch{"git-format-patch:"}
...@@ -25,7 +32,33 @@ func (p *patch) Inject(w http.ResponseWriter, r *http.Request, sendData string) ...@@ -25,7 +32,33 @@ func (p *patch) Inject(w http.ResponseWriter, r *http.Request, sendData string)
helper.Fail500(w, r, fmt.Errorf("SendPatch: unpack sendData: %v", err)) helper.Fail500(w, r, fmt.Errorf("SendPatch: unpack sendData: %v", err))
return return
} }
if params.GitalyServer.Address != "" {
handleSendPatchWithGitaly(w, r, &params)
} else {
handleSendPatchLocally(w, r, &params)
}
}
func handleSendPatchWithGitaly(w http.ResponseWriter, r *http.Request, params *patchParams) {
request := &pb.RawPatchRequest{}
if err := jsonpb.UnmarshalString(params.RawPatchRequest, request); err != nil {
helper.Fail500(w, r, fmt.Errorf("diff.RawPatch: %v", err))
}
diffClient, err := gitaly.NewDiffClient(params.GitalyServer)
if err != nil {
helper.Fail500(w, r, fmt.Errorf("diff.RawPatch: %v", err))
}
if err := diffClient.SendRawPatch(r.Context(), w, request); err != nil {
helper.LogError(
r,
&copyError{fmt.Errorf("diff.RawPatch: request=%v, err=%v", request, err)},
)
}
}
func handleSendPatchLocally(w http.ResponseWriter, r *http.Request, params *patchParams) {
log.Printf("SendPatch: sending patch between %q and %q for %q", params.ShaFrom, params.ShaTo, r.URL.Path) log.Printf("SendPatch: sending patch between %q and %q for %q", params.ShaFrom, params.ShaTo, r.URL.Path)
gitRange := fmt.Sprintf("%s..%s", params.ShaFrom, params.ShaTo) gitRange := fmt.Sprintf("%s..%s", params.ShaFrom, params.ShaTo)
......
package gitaly
import (
"context"
"fmt"
"io"
"net/http"
"gitlab.com/gitlab-org/gitaly/streamio"
pb "gitlab.com/gitlab-org/gitaly-proto/go"
)
type DiffClient struct {
pb.DiffServiceClient
}
func (client *DiffClient) SendRawDiff(ctx context.Context, w http.ResponseWriter, request *pb.RawDiffRequest) error {
c, err := client.RawDiff(ctx, request)
if err != nil {
return fmt.Errorf("rpc failed: %v", err)
}
w.Header().Del("Content-Length")
rr := streamio.NewReader(func() ([]byte, error) {
resp, err := c.Recv()
return resp.GetData(), err
})
if _, err := io.Copy(w, rr); err != nil {
return fmt.Errorf("copy rpc data: %v", err)
}
return nil
}
func (client *DiffClient) SendRawPatch(ctx context.Context, w http.ResponseWriter, request *pb.RawPatchRequest) error {
c, err := client.RawPatch(ctx, request)
if err != nil {
return fmt.Errorf("rpc failed: %v", err)
}
w.Header().Del("Content-Length")
rr := streamio.NewReader(func() ([]byte, error) {
resp, err := c.Recv()
return resp.GetData(), err
})
if _, err := io.Copy(w, rr); err != nil {
return fmt.Errorf("copy rpc data: %v", err)
}
return nil
}
...@@ -50,6 +50,15 @@ func NewRepositoryClient(server Server) (*RepositoryClient, error) { ...@@ -50,6 +50,15 @@ func NewRepositoryClient(server Server) (*RepositoryClient, error) {
return &RepositoryClient{grpcClient}, nil return &RepositoryClient{grpcClient}, nil
} }
func NewDiffClient(server Server) (*DiffClient, error) {
conn, err := getOrCreateConnection(server)
if err != nil {
return nil, err
}
grpcClient := pb.NewDiffServiceClient(conn)
return &DiffClient{grpcClient}, nil
}
func getOrCreateConnection(server Server) (*grpc.ClientConn, error) { func getOrCreateConnection(server Server) (*grpc.ClientConn, error) {
cache.RLock() cache.RLock()
conn := cache.connections[server] conn := cache.connections[server]
......
...@@ -25,6 +25,8 @@ var ( ...@@ -25,6 +25,8 @@ var (
GitalyInfoRefsResponseMock = strings.Repeat("Mock Gitaly InfoRefsResponse data", 100000) GitalyInfoRefsResponseMock = strings.Repeat("Mock Gitaly InfoRefsResponse data", 100000)
GitalyGetBlobResponseMock = strings.Repeat("Mock Gitaly GetBlobResponse data", 100000) GitalyGetBlobResponseMock = strings.Repeat("Mock Gitaly GetBlobResponse data", 100000)
GitalyGetArchiveResponseMock = strings.Repeat("Mock Gitaly GetArchiveResponse data", 100000) GitalyGetArchiveResponseMock = strings.Repeat("Mock Gitaly GetArchiveResponse data", 100000)
GitalyGetDiffResponseMock = strings.Repeat("Mock Gitaly GetDiffResponse data", 100000)
GitalyGetPatchResponseMock = strings.Repeat("Mock Gitaly GetPatchResponse data", 100000)
GitalyReceivePackResponseMock []byte GitalyReceivePackResponseMock []byte
GitalyUploadPackResponseMock []byte GitalyUploadPackResponseMock []byte
) )
...@@ -230,6 +232,45 @@ func (s *GitalyTestServer) GetArchive(in *pb.GetArchiveRequest, stream pb.Reposi ...@@ -230,6 +232,45 @@ func (s *GitalyTestServer) GetArchive(in *pb.GetArchiveRequest, stream pb.Reposi
return s.finalError() return s.finalError()
} }
func (s *GitalyTestServer) RawDiff(in *pb.RawDiffRequest, stream pb.DiffService_RawDiffServer) error {
nSends, err := sendBytes([]byte(GitalyGetDiffResponseMock), 100, func(p []byte) error {
return stream.Send(&pb.RawDiffResponse{
Data: p,
})
})
if err != nil {
return err
}
if nSends <= 1 {
panic("should have sent more than one message")
}
return s.finalError()
}
func (s *GitalyTestServer) RawPatch(in *pb.RawPatchRequest, stream pb.DiffService_RawPatchServer) error {
s.WaitGroup.Add(1)
defer s.WaitGroup.Done()
if err := validateRepository(in.GetRepository()); err != nil {
return err
}
nSends, err := sendBytes([]byte(GitalyGetPatchResponseMock), 100, func(p []byte) error {
return stream.Send(&pb.RawPatchResponse{
Data: p,
})
})
if err != nil {
return err
}
if nSends <= 1 {
panic("should have sent more than one message")
}
return s.finalError()
}
func (s *GitalyTestServer) RepositoryExists(context.Context, *pb.RepositoryExistsRequest) (*pb.RepositoryExistsResponse, error) { func (s *GitalyTestServer) RepositoryExists(context.Context, *pb.RepositoryExistsRequest) (*pb.RepositoryExistsResponse, error) {
return nil, nil return nil, nil
} }
...@@ -266,6 +307,18 @@ func (s *GitalyTestServer) Exists(context.Context, *pb.RepositoryExistsRequest) ...@@ -266,6 +307,18 @@ func (s *GitalyTestServer) Exists(context.Context, *pb.RepositoryExistsRequest)
return nil, nil return nil, nil
} }
func (s *GitalyTestServer) CommitDelta(in *pb.CommitDeltaRequest, stream pb.DiffService_CommitDeltaServer) error {
return nil
}
func (s *GitalyTestServer) CommitDiff(in *pb.CommitDiffRequest, stream pb.DiffService_CommitDiffServer) error {
return nil
}
func (s *GitalyTestServer) CommitPatch(in *pb.CommitPatchRequest, stream pb.DiffService_CommitPatchServer) error {
return nil
}
// sendBytes returns the number of times the 'sender' function was called and an error. // sendBytes returns the number of times the 'sender' function was called and an error.
func sendBytes(data []byte, chunkSize int, sender func([]byte) error) (int, error) { func sendBytes(data []byte, chunkSize int, sender func([]byte) error) (int, error) {
i := 0 i := 0
......
// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2015 The Go Authors. All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/*
Package jsonpb provides marshaling and unmarshaling between protocol buffers and JSON.
It follows the specification at https://developers.google.com/protocol-buffers/docs/proto3#json.
This package produces a different output than the standard "encoding/json" package,
which does not operate correctly on protocol buffers.
*/
package jsonpb
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"math"
"reflect"
"sort"
"strconv"
"strings"
"time"
"github.com/golang/protobuf/proto"
stpb "github.com/golang/protobuf/ptypes/struct"
)
// Marshaler is a configurable object for converting between
// protocol buffer objects and a JSON representation for them.
type Marshaler struct {
// Whether to render enum values as integers, as opposed to string values.
EnumsAsInts bool
// Whether to render fields with zero values.
EmitDefaults bool
// A string to indent each level by. The presence of this field will
// also cause a space to appear between the field separator and
// value, and for newlines to be appear between fields and array
// elements.
Indent string
// Whether to use the original (.proto) name for fields.
OrigName bool
// A custom URL resolver to use when marshaling Any messages to JSON.
// If unset, the default resolution strategy is to extract the
// fully-qualified type name from the type URL and pass that to
// proto.MessageType(string).
AnyResolver AnyResolver
}
// AnyResolver takes a type URL, present in an Any message, and resolves it into
// an instance of the associated message.
type AnyResolver interface {
Resolve(typeUrl string) (proto.Message, error)
}
func defaultResolveAny(typeUrl string) (proto.Message, error) {
// Only the part of typeUrl after the last slash is relevant.
mname := typeUrl
if slash := strings.LastIndex(mname, "/"); slash >= 0 {
mname = mname[slash+1:]
}
mt := proto.MessageType(mname)
if mt == nil {
return nil, fmt.Errorf("unknown message type %q", mname)
}
return reflect.New(mt.Elem()).Interface().(proto.Message), nil
}
// JSONPBMarshaler is implemented by protobuf messages that customize the
// way they are marshaled to JSON. Messages that implement this should
// also implement JSONPBUnmarshaler so that the custom format can be
// parsed.
type JSONPBMarshaler interface {
MarshalJSONPB(*Marshaler) ([]byte, error)
}
// JSONPBUnmarshaler is implemented by protobuf messages that customize
// the way they are unmarshaled from JSON. Messages that implement this
// should also implement JSONPBMarshaler so that the custom format can be
// produced.
type JSONPBUnmarshaler interface {
UnmarshalJSONPB(*Unmarshaler, []byte) error
}
// Marshal marshals a protocol buffer into JSON.
func (m *Marshaler) Marshal(out io.Writer, pb proto.Message) error {
writer := &errWriter{writer: out}
return m.marshalObject(writer, pb, "", "")
}
// MarshalToString converts a protocol buffer object to JSON string.
func (m *Marshaler) MarshalToString(pb proto.Message) (string, error) {
var buf bytes.Buffer
if err := m.Marshal(&buf, pb); err != nil {
return "", err
}
return buf.String(), nil
}
type int32Slice []int32
var nonFinite = map[string]float64{
`"NaN"`: math.NaN(),
`"Infinity"`: math.Inf(1),
`"-Infinity"`: math.Inf(-1),
}
// For sorting extensions ids to ensure stable output.
func (s int32Slice) Len() int { return len(s) }
func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] }
func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
type wkt interface {
XXX_WellKnownType() string
}
// marshalObject writes a struct to the Writer.
func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent, typeURL string) error {
if jsm, ok := v.(JSONPBMarshaler); ok {
b, err := jsm.MarshalJSONPB(m)
if err != nil {
return err
}
if typeURL != "" {
// we are marshaling this object to an Any type
var js map[string]*json.RawMessage
if err = json.Unmarshal(b, &js); err != nil {
return fmt.Errorf("type %T produced invalid JSON: %v", v, err)
}
turl, err := json.Marshal(typeURL)
if err != nil {
return fmt.Errorf("failed to marshal type URL %q to JSON: %v", typeURL, err)
}
js["@type"] = (*json.RawMessage)(&turl)
if b, err = json.Marshal(js); err != nil {
return err
}
}
out.write(string(b))
return out.err
}
s := reflect.ValueOf(v).Elem()
// Handle well-known types.
if wkt, ok := v.(wkt); ok {
switch wkt.XXX_WellKnownType() {
case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value",
"Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue":
// "Wrappers use the same representation in JSON
// as the wrapped primitive type, ..."
sprop := proto.GetProperties(s.Type())
return m.marshalValue(out, sprop.Prop[0], s.Field(0), indent)
case "Any":
// Any is a bit more involved.
return m.marshalAny(out, v, indent)
case "Duration":
// "Generated output always contains 3, 6, or 9 fractional digits,
// depending on required precision."
s, ns := s.Field(0).Int(), s.Field(1).Int()
d := time.Duration(s)*time.Second + time.Duration(ns)*time.Nanosecond
x := fmt.Sprintf("%.9f", d.Seconds())
x = strings.TrimSuffix(x, "000")
x = strings.TrimSuffix(x, "000")
out.write(`"`)
out.write(x)
out.write(`s"`)
return out.err
case "Struct", "ListValue":
// Let marshalValue handle the `Struct.fields` map or the `ListValue.values` slice.
// TODO: pass the correct Properties if needed.
return m.marshalValue(out, &proto.Properties{}, s.Field(0), indent)
case "Timestamp":
// "RFC 3339, where generated output will always be Z-normalized
// and uses 3, 6 or 9 fractional digits."
s, ns := s.Field(0).Int(), s.Field(1).Int()
t := time.Unix(s, ns).UTC()
// time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits).
x := t.Format("2006-01-02T15:04:05.000000000")
x = strings.TrimSuffix(x, "000")
x = strings.TrimSuffix(x, "000")
out.write(`"`)
out.write(x)
out.write(`Z"`)
return out.err
case "Value":
// Value has a single oneof.
kind := s.Field(0)
if kind.IsNil() {
// "absence of any variant indicates an error"
return errors.New("nil Value")
}
// oneof -> *T -> T -> T.F
x := kind.Elem().Elem().Field(0)
// TODO: pass the correct Properties if needed.
return m.marshalValue(out, &proto.Properties{}, x, indent)
}
}
out.write("{")
if m.Indent != "" {
out.write("\n")
}
firstField := true
if typeURL != "" {
if err := m.marshalTypeURL(out, indent, typeURL); err != nil {
return err
}
firstField = false
}
for i := 0; i < s.NumField(); i++ {
value := s.Field(i)
valueField := s.Type().Field(i)
if strings.HasPrefix(valueField.Name, "XXX_") {
continue
}
// IsNil will panic on most value kinds.
switch value.Kind() {
case reflect.Chan, reflect.Func, reflect.Interface:
if value.IsNil() {
continue
}
}
if !m.EmitDefaults {
switch value.Kind() {
case reflect.Bool:
if !value.Bool() {
continue
}
case reflect.Int32, reflect.Int64:
if value.Int() == 0 {
continue
}
case reflect.Uint32, reflect.Uint64:
if value.Uint() == 0 {
continue
}
case reflect.Float32, reflect.Float64:
if value.Float() == 0 {
continue
}
case reflect.String:
if value.Len() == 0 {
continue
}
case reflect.Map, reflect.Ptr, reflect.Slice:
if value.IsNil() {
continue
}
}
}
// Oneof fields need special handling.
if valueField.Tag.Get("protobuf_oneof") != "" {
// value is an interface containing &T{real_value}.
sv := value.Elem().Elem() // interface -> *T -> T
value = sv.Field(0)
valueField = sv.Type().Field(0)
}
prop := jsonProperties(valueField, m.OrigName)
if !firstField {
m.writeSep(out)
}
if err := m.marshalField(out, prop, value, indent); err != nil {
return err
}
firstField = false
}
// Handle proto2 extensions.
if ep, ok := v.(proto.Message); ok {
extensions := proto.RegisteredExtensions(v)
// Sort extensions for stable output.
ids := make([]int32, 0, len(extensions))
for id, desc := range extensions {
if !proto.HasExtension(ep, desc) {
continue
}
ids = append(ids, id)
}
sort.Sort(int32Slice(ids))
for _, id := range ids {
desc := extensions[id]
if desc == nil {
// unknown extension
continue
}
ext, extErr := proto.GetExtension(ep, desc)
if extErr != nil {
return extErr
}
value := reflect.ValueOf(ext)
var prop proto.Properties
prop.Parse(desc.Tag)
prop.JSONName = fmt.Sprintf("[%s]", desc.Name)
if !firstField {
m.writeSep(out)
}
if err := m.marshalField(out, &prop, value, indent); err != nil {
return err
}
firstField = false
}
}
if m.Indent != "" {
out.write("\n")
out.write(indent)
}
out.write("}")
return out.err
}
func (m *Marshaler) writeSep(out *errWriter) {
if m.Indent != "" {
out.write(",\n")
} else {
out.write(",")
}
}
func (m *Marshaler) marshalAny(out *errWriter, any proto.Message, indent string) error {
// "If the Any contains a value that has a special JSON mapping,
// it will be converted as follows: {"@type": xxx, "value": yyy}.
// Otherwise, the value will be converted into a JSON object,
// and the "@type" field will be inserted to indicate the actual data type."
v := reflect.ValueOf(any).Elem()
turl := v.Field(0).String()
val := v.Field(1).Bytes()
var msg proto.Message
var err error
if m.AnyResolver != nil {
msg, err = m.AnyResolver.Resolve(turl)
} else {
msg, err = defaultResolveAny(turl)
}
if err != nil {
return err
}
if err := proto.Unmarshal(val, msg); err != nil {
return err
}
if _, ok := msg.(wkt); ok {
out.write("{")
if m.Indent != "" {
out.write("\n")
}
if err := m.marshalTypeURL(out, indent, turl); err != nil {
return err
}
m.writeSep(out)
if m.Indent != "" {
out.write(indent)
out.write(m.Indent)
out.write(`"value": `)
} else {
out.write(`"value":`)
}
if err := m.marshalObject(out, msg, indent+m.Indent, ""); err != nil {
return err
}
if m.Indent != "" {
out.write("\n")
out.write(indent)
}
out.write("}")
return out.err
}
return m.marshalObject(out, msg, indent, turl)
}
func (m *Marshaler) marshalTypeURL(out *errWriter, indent, typeURL string) error {
if m.Indent != "" {
out.write(indent)
out.write(m.Indent)
}
out.write(`"@type":`)
if m.Indent != "" {
out.write(" ")
}
b, err := json.Marshal(typeURL)
if err != nil {
return err
}
out.write(string(b))
return out.err
}
// marshalField writes field description and value to the Writer.
func (m *Marshaler) marshalField(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error {
if m.Indent != "" {
out.write(indent)
out.write(m.Indent)
}
out.write(`"`)
out.write(prop.JSONName)
out.write(`":`)
if m.Indent != "" {
out.write(" ")
}
if err := m.marshalValue(out, prop, v, indent); err != nil {
return err
}
return nil
}
// marshalValue writes the value to the Writer.
func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error {
var err error
v = reflect.Indirect(v)
// Handle nil pointer
if v.Kind() == reflect.Invalid {
out.write("null")
return out.err
}
// Handle repeated elements.
if v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 {
out.write("[")
comma := ""
for i := 0; i < v.Len(); i++ {
sliceVal := v.Index(i)
out.write(comma)
if m.Indent != "" {
out.write("\n")
out.write(indent)
out.write(m.Indent)
out.write(m.Indent)
}
if err := m.marshalValue(out, prop, sliceVal, indent+m.Indent); err != nil {
return err
}
comma = ","
}
if m.Indent != "" {
out.write("\n")
out.write(indent)
out.write(m.Indent)
}
out.write("]")
return out.err
}
// Handle well-known types.
// Most are handled up in marshalObject (because 99% are messages).
if wkt, ok := v.Interface().(wkt); ok {
switch wkt.XXX_WellKnownType() {
case "NullValue":
out.write("null")
return out.err
}
}
// Handle enumerations.
if !m.EnumsAsInts && prop.Enum != "" {
// Unknown enum values will are stringified by the proto library as their
// value. Such values should _not_ be quoted or they will be interpreted
// as an enum string instead of their value.
enumStr := v.Interface().(fmt.Stringer).String()
var valStr string
if v.Kind() == reflect.Ptr {
valStr = strconv.Itoa(int(v.Elem().Int()))
} else {
valStr = strconv.Itoa(int(v.Int()))
}
isKnownEnum := enumStr != valStr
if isKnownEnum {
out.write(`"`)
}
out.write(enumStr)
if isKnownEnum {
out.write(`"`)
}
return out.err
}
// Handle nested messages.
if v.Kind() == reflect.Struct {
return m.marshalObject(out, v.Addr().Interface().(proto.Message), indent+m.Indent, "")
}
// Handle maps.
// Since Go randomizes map iteration, we sort keys for stable output.
if v.Kind() == reflect.Map {
out.write(`{`)
keys := v.MapKeys()
sort.Sort(mapKeys(keys))
for i, k := range keys {
if i > 0 {
out.write(`,`)
}
if m.Indent != "" {
out.write("\n")
out.write(indent)
out.write(m.Indent)
out.write(m.Indent)
}
b, err := json.Marshal(k.Interface())
if err != nil {
return err
}
s := string(b)
// If the JSON is not a string value, encode it again to make it one.
if !strings.HasPrefix(s, `"`) {
b, err := json.Marshal(s)
if err != nil {
return err
}
s = string(b)
}
out.write(s)
out.write(`:`)
if m.Indent != "" {
out.write(` `)
}
if err := m.marshalValue(out, prop, v.MapIndex(k), indent+m.Indent); err != nil {
return err
}
}
if m.Indent != "" {
out.write("\n")
out.write(indent)
out.write(m.Indent)
}
out.write(`}`)
return out.err
}
// Handle non-finite floats, e.g. NaN, Infinity and -Infinity.
if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 {
f := v.Float()
var sval string
switch {
case math.IsInf(f, 1):
sval = `"Infinity"`
case math.IsInf(f, -1):
sval = `"-Infinity"`
case math.IsNaN(f):
sval = `"NaN"`
}
if sval != "" {
out.write(sval)
return out.err
}
}
// Default handling defers to the encoding/json library.
b, err := json.Marshal(v.Interface())
if err != nil {
return err
}
needToQuote := string(b[0]) != `"` && (v.Kind() == reflect.Int64 || v.Kind() == reflect.Uint64)
if needToQuote {
out.write(`"`)
}
out.write(string(b))
if needToQuote {
out.write(`"`)
}
return out.err
}
// Unmarshaler is a configurable object for converting from a JSON
// representation to a protocol buffer object.
type Unmarshaler struct {
// Whether to allow messages to contain unknown fields, as opposed to
// failing to unmarshal.
AllowUnknownFields bool
// A custom URL resolver to use when unmarshaling Any messages from JSON.
// If unset, the default resolution strategy is to extract the
// fully-qualified type name from the type URL and pass that to
// proto.MessageType(string).
AnyResolver AnyResolver
}
// UnmarshalNext unmarshals the next protocol buffer from a JSON object stream.
// This function is lenient and will decode any options permutations of the
// related Marshaler.
func (u *Unmarshaler) UnmarshalNext(dec *json.Decoder, pb proto.Message) error {
inputValue := json.RawMessage{}
if err := dec.Decode(&inputValue); err != nil {
return err
}
return u.unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue, nil)
}
// Unmarshal unmarshals a JSON object stream into a protocol
// buffer. This function is lenient and will decode any options
// permutations of the related Marshaler.
func (u *Unmarshaler) Unmarshal(r io.Reader, pb proto.Message) error {
dec := json.NewDecoder(r)
return u.UnmarshalNext(dec, pb)
}
// UnmarshalNext unmarshals the next protocol buffer from a JSON object stream.
// This function is lenient and will decode any options permutations of the
// related Marshaler.
func UnmarshalNext(dec *json.Decoder, pb proto.Message) error {
return new(Unmarshaler).UnmarshalNext(dec, pb)
}
// Unmarshal unmarshals a JSON object stream into a protocol
// buffer. This function is lenient and will decode any options
// permutations of the related Marshaler.
func Unmarshal(r io.Reader, pb proto.Message) error {
return new(Unmarshaler).Unmarshal(r, pb)
}
// UnmarshalString will populate the fields of a protocol buffer based
// on a JSON string. This function is lenient and will decode any options
// permutations of the related Marshaler.
func UnmarshalString(str string, pb proto.Message) error {
return new(Unmarshaler).Unmarshal(strings.NewReader(str), pb)
}
// unmarshalValue converts/copies a value into the target.
// prop may be nil.
func (u *Unmarshaler) unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *proto.Properties) error {
targetType := target.Type()
// Allocate memory for pointer fields.
if targetType.Kind() == reflect.Ptr {
// If input value is "null" and target is a pointer type, then the field should be treated as not set
// UNLESS the target is structpb.Value, in which case it should be set to structpb.NullValue.
_, isJSONPBUnmarshaler := target.Interface().(JSONPBUnmarshaler)
if string(inputValue) == "null" && targetType != reflect.TypeOf(&stpb.Value{}) && !isJSONPBUnmarshaler {
return nil
}
target.Set(reflect.New(targetType.Elem()))
return u.unmarshalValue(target.Elem(), inputValue, prop)
}
if jsu, ok := target.Addr().Interface().(JSONPBUnmarshaler); ok {
return jsu.UnmarshalJSONPB(u, []byte(inputValue))
}
// Handle well-known types that are not pointers.
if w, ok := target.Addr().Interface().(wkt); ok {
switch w.XXX_WellKnownType() {
case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value",
"Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue":
return u.unmarshalValue(target.Field(0), inputValue, prop)
case "Any":
// Use json.RawMessage pointer type instead of value to support pre-1.8 version.
// 1.8 changed RawMessage.MarshalJSON from pointer type to value type, see
// https://github.com/golang/go/issues/14493
var jsonFields map[string]*json.RawMessage
if err := json.Unmarshal(inputValue, &jsonFields); err != nil {
return err
}
val, ok := jsonFields["@type"]
if !ok || val == nil {
return errors.New("Any JSON doesn't have '@type'")
}
var turl string
if err := json.Unmarshal([]byte(*val), &turl); err != nil {
return fmt.Errorf("can't unmarshal Any's '@type': %q", *val)
}
target.Field(0).SetString(turl)
var m proto.Message
var err error
if u.AnyResolver != nil {
m, err = u.AnyResolver.Resolve(turl)
} else {
m, err = defaultResolveAny(turl)
}
if err != nil {
return err
}
if _, ok := m.(wkt); ok {
val, ok := jsonFields["value"]
if !ok {
return errors.New("Any JSON doesn't have 'value'")
}
if err := u.unmarshalValue(reflect.ValueOf(m).Elem(), *val, nil); err != nil {
return fmt.Errorf("can't unmarshal Any nested proto %T: %v", m, err)
}
} else {
delete(jsonFields, "@type")
nestedProto, err := json.Marshal(jsonFields)
if err != nil {
return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err)
}
if err = u.unmarshalValue(reflect.ValueOf(m).Elem(), nestedProto, nil); err != nil {
return fmt.Errorf("can't unmarshal Any nested proto %T: %v", m, err)
}
}
b, err := proto.Marshal(m)
if err != nil {
return fmt.Errorf("can't marshal proto %T into Any.Value: %v", m, err)
}
target.Field(1).SetBytes(b)
return nil
case "Duration":
unq, err := strconv.Unquote(string(inputValue))
if err != nil {
return err
}
d, err := time.ParseDuration(unq)
if err != nil {
return fmt.Errorf("bad Duration: %v", err)
}
ns := d.Nanoseconds()
s := ns / 1e9
ns %= 1e9
target.Field(0).SetInt(s)
target.Field(1).SetInt(ns)
return nil
case "Timestamp":
unq, err := strconv.Unquote(string(inputValue))
if err != nil {
return err
}
t, err := time.Parse(time.RFC3339Nano, unq)
if err != nil {
return fmt.Errorf("bad Timestamp: %v", err)
}
target.Field(0).SetInt(t.Unix())
target.Field(1).SetInt(int64(t.Nanosecond()))
return nil
case "Struct":
var m map[string]json.RawMessage
if err := json.Unmarshal(inputValue, &m); err != nil {
return fmt.Errorf("bad StructValue: %v", err)
}
target.Field(0).Set(reflect.ValueOf(map[string]*stpb.Value{}))
for k, jv := range m {
pv := &stpb.Value{}
if err := u.unmarshalValue(reflect.ValueOf(pv).Elem(), jv, prop); err != nil {
return fmt.Errorf("bad value in StructValue for key %q: %v", k, err)
}
target.Field(0).SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(pv))
}
return nil
case "ListValue":
var s []json.RawMessage
if err := json.Unmarshal(inputValue, &s); err != nil {
return fmt.Errorf("bad ListValue: %v", err)
}
target.Field(0).Set(reflect.ValueOf(make([]*stpb.Value, len(s), len(s))))
for i, sv := range s {
if err := u.unmarshalValue(target.Field(0).Index(i), sv, prop); err != nil {
return err
}
}
return nil
case "Value":
ivStr := string(inputValue)
if ivStr == "null" {
target.Field(0).Set(reflect.ValueOf(&stpb.Value_NullValue{}))
} else if v, err := strconv.ParseFloat(ivStr, 0); err == nil {
target.Field(0).Set(reflect.ValueOf(&stpb.Value_NumberValue{v}))
} else if v, err := strconv.Unquote(ivStr); err == nil {
target.Field(0).Set(reflect.ValueOf(&stpb.Value_StringValue{v}))
} else if v, err := strconv.ParseBool(ivStr); err == nil {
target.Field(0).Set(reflect.ValueOf(&stpb.Value_BoolValue{v}))
} else if err := json.Unmarshal(inputValue, &[]json.RawMessage{}); err == nil {
lv := &stpb.ListValue{}
target.Field(0).Set(reflect.ValueOf(&stpb.Value_ListValue{lv}))
return u.unmarshalValue(reflect.ValueOf(lv).Elem(), inputValue, prop)
} else if err := json.Unmarshal(inputValue, &map[string]json.RawMessage{}); err == nil {
sv := &stpb.Struct{}
target.Field(0).Set(reflect.ValueOf(&stpb.Value_StructValue{sv}))
return u.unmarshalValue(reflect.ValueOf(sv).Elem(), inputValue, prop)
} else {
return fmt.Errorf("unrecognized type for Value %q", ivStr)
}
return nil
}
}
// Handle enums, which have an underlying type of int32,
// and may appear as strings.
// The case of an enum appearing as a number is handled
// at the bottom of this function.
if inputValue[0] == '"' && prop != nil && prop.Enum != "" {
vmap := proto.EnumValueMap(prop.Enum)
// Don't need to do unquoting; valid enum names
// are from a limited character set.
s := inputValue[1 : len(inputValue)-1]
n, ok := vmap[string(s)]
if !ok {
return fmt.Errorf("unknown value %q for enum %s", s, prop.Enum)
}
if target.Kind() == reflect.Ptr { // proto2
target.Set(reflect.New(targetType.Elem()))
target = target.Elem()
}
target.SetInt(int64(n))
return nil
}
// Handle nested messages.
if targetType.Kind() == reflect.Struct {
var jsonFields map[string]json.RawMessage
if err := json.Unmarshal(inputValue, &jsonFields); err != nil {
return err
}
consumeField := func(prop *proto.Properties) (json.RawMessage, bool) {
// Be liberal in what names we accept; both orig_name and camelName are okay.
fieldNames := acceptedJSONFieldNames(prop)
vOrig, okOrig := jsonFields[fieldNames.orig]
vCamel, okCamel := jsonFields[fieldNames.camel]
if !okOrig && !okCamel {
return nil, false
}
// If, for some reason, both are present in the data, favour the camelName.
var raw json.RawMessage
if okOrig {
raw = vOrig
delete(jsonFields, fieldNames.orig)
}
if okCamel {
raw = vCamel
delete(jsonFields, fieldNames.camel)
}
return raw, true
}
sprops := proto.GetProperties(targetType)
for i := 0; i < target.NumField(); i++ {
ft := target.Type().Field(i)
if strings.HasPrefix(ft.Name, "XXX_") {
continue
}
valueForField, ok := consumeField(sprops.Prop[i])
if !ok {
continue
}
if err := u.unmarshalValue(target.Field(i), valueForField, sprops.Prop[i]); err != nil {
return err
}
}
// Check for any oneof fields.
if len(jsonFields) > 0 {
for _, oop := range sprops.OneofTypes {
raw, ok := consumeField(oop.Prop)
if !ok {
continue
}
nv := reflect.New(oop.Type.Elem())
target.Field(oop.Field).Set(nv)
if err := u.unmarshalValue(nv.Elem().Field(0), raw, oop.Prop); err != nil {
return err
}
}
}
// Handle proto2 extensions.
if len(jsonFields) > 0 {
if ep, ok := target.Addr().Interface().(proto.Message); ok {
for _, ext := range proto.RegisteredExtensions(ep) {
name := fmt.Sprintf("[%s]", ext.Name)
raw, ok := jsonFields[name]
if !ok {
continue
}
delete(jsonFields, name)
nv := reflect.New(reflect.TypeOf(ext.ExtensionType).Elem())
if err := u.unmarshalValue(nv.Elem(), raw, nil); err != nil {
return err
}
if err := proto.SetExtension(ep, ext, nv.Interface()); err != nil {
return err
}
}
}
}
if !u.AllowUnknownFields && len(jsonFields) > 0 {
// Pick any field to be the scapegoat.
var f string
for fname := range jsonFields {
f = fname
break
}
return fmt.Errorf("unknown field %q in %v", f, targetType)
}
return nil
}
// Handle arrays (which aren't encoded bytes)
if targetType.Kind() == reflect.Slice && targetType.Elem().Kind() != reflect.Uint8 {
var slc []json.RawMessage
if err := json.Unmarshal(inputValue, &slc); err != nil {
return err
}
if slc != nil {
l := len(slc)
target.Set(reflect.MakeSlice(targetType, l, l))
for i := 0; i < l; i++ {
if err := u.unmarshalValue(target.Index(i), slc[i], prop); err != nil {
return err
}
}
}
return nil
}
// Handle maps (whose keys are always strings)
if targetType.Kind() == reflect.Map {
var mp map[string]json.RawMessage
if err := json.Unmarshal(inputValue, &mp); err != nil {
return err
}
if mp != nil {
target.Set(reflect.MakeMap(targetType))
var keyprop, valprop *proto.Properties
if prop != nil {
// These could still be nil if the protobuf metadata is broken somehow.
// TODO: This won't work because the fields are unexported.
// We should probably just reparse them.
//keyprop, valprop = prop.mkeyprop, prop.mvalprop
}
for ks, raw := range mp {
// Unmarshal map key. The core json library already decoded the key into a
// string, so we handle that specially. Other types were quoted post-serialization.
var k reflect.Value
if targetType.Key().Kind() == reflect.String {
k = reflect.ValueOf(ks)
} else {
k = reflect.New(targetType.Key()).Elem()
if err := u.unmarshalValue(k, json.RawMessage(ks), keyprop); err != nil {
return err
}
}
// Unmarshal map value.
v := reflect.New(targetType.Elem()).Elem()
if err := u.unmarshalValue(v, raw, valprop); err != nil {
return err
}
target.SetMapIndex(k, v)
}
}
return nil
}
// 64-bit integers can be encoded as strings. In this case we drop
// the quotes and proceed as normal.
isNum := targetType.Kind() == reflect.Int64 || targetType.Kind() == reflect.Uint64
if isNum && strings.HasPrefix(string(inputValue), `"`) {
inputValue = inputValue[1 : len(inputValue)-1]
}
// Non-finite numbers can be encoded as strings.
isFloat := targetType.Kind() == reflect.Float32 || targetType.Kind() == reflect.Float64
if isFloat {
if num, ok := nonFinite[string(inputValue)]; ok {
target.SetFloat(num)
return nil
}
}
// Use the encoding/json for parsing other value types.
return json.Unmarshal(inputValue, target.Addr().Interface())
}
// jsonProperties returns parsed proto.Properties for the field and corrects JSONName attribute.
func jsonProperties(f reflect.StructField, origName bool) *proto.Properties {
var prop proto.Properties
prop.Init(f.Type, f.Name, f.Tag.Get("protobuf"), &f)
if origName || prop.JSONName == "" {
prop.JSONName = prop.OrigName
}
return &prop
}
type fieldNames struct {
orig, camel string
}
func acceptedJSONFieldNames(prop *proto.Properties) fieldNames {
opts := fieldNames{orig: prop.OrigName, camel: prop.OrigName}
if prop.JSONName != "" {
opts.camel = prop.JSONName
}
return opts
}
// Writer wrapper inspired by https://blog.golang.org/errors-are-values
type errWriter struct {
writer io.Writer
err error
}
func (w *errWriter) write(str string) {
if w.err != nil {
return
}
_, w.err = w.writer.Write([]byte(str))
}
// Map fields may have key types of non-float scalars, strings and enums.
// The easiest way to sort them in some deterministic order is to use fmt.
// If this turns out to be inefficient we can always consider other options,
// such as doing a Schwartzian transform.
//
// Numeric keys are sorted in numeric order per
// https://developers.google.com/protocol-buffers/docs/proto#maps.
type mapKeys []reflect.Value
func (s mapKeys) Len() int { return len(s) }
func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s mapKeys) Less(i, j int) bool {
if k := s[i].Kind(); k == s[j].Kind() {
switch k {
case reflect.Int32, reflect.Int64:
return s[i].Int() < s[j].Int()
case reflect.Uint32, reflect.Uint64:
return s[i].Uint() < s[j].Uint()
}
}
return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface())
}
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: google/protobuf/struct.proto
/*
Package structpb is a generated protocol buffer package.
It is generated from these files:
google/protobuf/struct.proto
It has these top-level messages:
Struct
Value
ListValue
*/
package structpb
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// `NullValue` is a singleton enumeration to represent the null value for the
// `Value` type union.
//
// The JSON representation for `NullValue` is JSON `null`.
type NullValue int32
const (
// Null value.
NullValue_NULL_VALUE NullValue = 0
)
var NullValue_name = map[int32]string{
0: "NULL_VALUE",
}
var NullValue_value = map[string]int32{
"NULL_VALUE": 0,
}
func (x NullValue) String() string {
return proto.EnumName(NullValue_name, int32(x))
}
func (NullValue) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (NullValue) XXX_WellKnownType() string { return "NullValue" }
// `Struct` represents a structured data value, consisting of fields
// which map to dynamically typed values. In some languages, `Struct`
// might be supported by a native representation. For example, in
// scripting languages like JS a struct is represented as an
// object. The details of that representation are described together
// with the proto support for the language.
//
// The JSON representation for `Struct` is JSON object.
type Struct struct {
// Unordered map of dynamically typed values.
Fields map[string]*Value `protobuf:"bytes,1,rep,name=fields" json:"fields,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
}
func (m *Struct) Reset() { *m = Struct{} }
func (m *Struct) String() string { return proto.CompactTextString(m) }
func (*Struct) ProtoMessage() {}
func (*Struct) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (*Struct) XXX_WellKnownType() string { return "Struct" }
func (m *Struct) GetFields() map[string]*Value {
if m != nil {
return m.Fields
}
return nil
}
// `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.
//
// The JSON representation for `Value` is JSON value.
type Value struct {
// The kind of value.
//
// Types that are valid to be assigned to Kind:
// *Value_NullValue
// *Value_NumberValue
// *Value_StringValue
// *Value_BoolValue
// *Value_StructValue
// *Value_ListValue
Kind isValue_Kind `protobuf_oneof:"kind"`
}
func (m *Value) Reset() { *m = Value{} }
func (m *Value) String() string { return proto.CompactTextString(m) }
func (*Value) ProtoMessage() {}
func (*Value) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (*Value) XXX_WellKnownType() string { return "Value" }
type isValue_Kind interface {
isValue_Kind()
}
type Value_NullValue struct {
NullValue NullValue `protobuf:"varint,1,opt,name=null_value,json=nullValue,enum=google.protobuf.NullValue,oneof"`
}
type Value_NumberValue struct {
NumberValue float64 `protobuf:"fixed64,2,opt,name=number_value,json=numberValue,oneof"`
}
type Value_StringValue struct {
StringValue string `protobuf:"bytes,3,opt,name=string_value,json=stringValue,oneof"`
}
type Value_BoolValue struct {
BoolValue bool `protobuf:"varint,4,opt,name=bool_value,json=boolValue,oneof"`
}
type Value_StructValue struct {
StructValue *Struct `protobuf:"bytes,5,opt,name=struct_value,json=structValue,oneof"`
}
type Value_ListValue struct {
ListValue *ListValue `protobuf:"bytes,6,opt,name=list_value,json=listValue,oneof"`
}
func (*Value_NullValue) isValue_Kind() {}
func (*Value_NumberValue) isValue_Kind() {}
func (*Value_StringValue) isValue_Kind() {}
func (*Value_BoolValue) isValue_Kind() {}
func (*Value_StructValue) isValue_Kind() {}
func (*Value_ListValue) isValue_Kind() {}
func (m *Value) GetKind() isValue_Kind {
if m != nil {
return m.Kind
}
return nil
}
func (m *Value) GetNullValue() NullValue {
if x, ok := m.GetKind().(*Value_NullValue); ok {
return x.NullValue
}
return NullValue_NULL_VALUE
}
func (m *Value) GetNumberValue() float64 {
if x, ok := m.GetKind().(*Value_NumberValue); ok {
return x.NumberValue
}
return 0
}
func (m *Value) GetStringValue() string {
if x, ok := m.GetKind().(*Value_StringValue); ok {
return x.StringValue
}
return ""
}
func (m *Value) GetBoolValue() bool {
if x, ok := m.GetKind().(*Value_BoolValue); ok {
return x.BoolValue
}
return false
}
func (m *Value) GetStructValue() *Struct {
if x, ok := m.GetKind().(*Value_StructValue); ok {
return x.StructValue
}
return nil
}
func (m *Value) GetListValue() *ListValue {
if x, ok := m.GetKind().(*Value_ListValue); ok {
return x.ListValue
}
return nil
}
// XXX_OneofFuncs is for the internal use of the proto package.
func (*Value) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
return _Value_OneofMarshaler, _Value_OneofUnmarshaler, _Value_OneofSizer, []interface{}{
(*Value_NullValue)(nil),
(*Value_NumberValue)(nil),
(*Value_StringValue)(nil),
(*Value_BoolValue)(nil),
(*Value_StructValue)(nil),
(*Value_ListValue)(nil),
}
}
func _Value_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
m := msg.(*Value)
// kind
switch x := m.Kind.(type) {
case *Value_NullValue:
b.EncodeVarint(1<<3 | proto.WireVarint)
b.EncodeVarint(uint64(x.NullValue))
case *Value_NumberValue:
b.EncodeVarint(2<<3 | proto.WireFixed64)
b.EncodeFixed64(math.Float64bits(x.NumberValue))
case *Value_StringValue:
b.EncodeVarint(3<<3 | proto.WireBytes)
b.EncodeStringBytes(x.StringValue)
case *Value_BoolValue:
t := uint64(0)
if x.BoolValue {
t = 1
}
b.EncodeVarint(4<<3 | proto.WireVarint)
b.EncodeVarint(t)
case *Value_StructValue:
b.EncodeVarint(5<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.StructValue); err != nil {
return err
}
case *Value_ListValue:
b.EncodeVarint(6<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.ListValue); err != nil {
return err
}
case nil:
default:
return fmt.Errorf("Value.Kind has unexpected type %T", x)
}
return nil
}
func _Value_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
m := msg.(*Value)
switch tag {
case 1: // kind.null_value
if wire != proto.WireVarint {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeVarint()
m.Kind = &Value_NullValue{NullValue(x)}
return true, err
case 2: // kind.number_value
if wire != proto.WireFixed64 {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeFixed64()
m.Kind = &Value_NumberValue{math.Float64frombits(x)}
return true, err
case 3: // kind.string_value
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeStringBytes()
m.Kind = &Value_StringValue{x}
return true, err
case 4: // kind.bool_value
if wire != proto.WireVarint {
return true, proto.ErrInternalBadWireType
}
x, err := b.DecodeVarint()
m.Kind = &Value_BoolValue{x != 0}
return true, err
case 5: // kind.struct_value
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(Struct)
err := b.DecodeMessage(msg)
m.Kind = &Value_StructValue{msg}
return true, err
case 6: // kind.list_value
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(ListValue)
err := b.DecodeMessage(msg)
m.Kind = &Value_ListValue{msg}
return true, err
default:
return false, nil
}
}
func _Value_OneofSizer(msg proto.Message) (n int) {
m := msg.(*Value)
// kind
switch x := m.Kind.(type) {
case *Value_NullValue:
n += proto.SizeVarint(1<<3 | proto.WireVarint)
n += proto.SizeVarint(uint64(x.NullValue))
case *Value_NumberValue:
n += proto.SizeVarint(2<<3 | proto.WireFixed64)
n += 8
case *Value_StringValue:
n += proto.SizeVarint(3<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(len(x.StringValue)))
n += len(x.StringValue)
case *Value_BoolValue:
n += proto.SizeVarint(4<<3 | proto.WireVarint)
n += 1
case *Value_StructValue:
s := proto.Size(x.StructValue)
n += proto.SizeVarint(5<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case *Value_ListValue:
s := proto.Size(x.ListValue)
n += proto.SizeVarint(6<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case nil:
default:
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
}
return n
}
// `ListValue` is a wrapper around a repeated field of values.
//
// The JSON representation for `ListValue` is JSON array.
type ListValue struct {
// Repeated field of dynamically typed values.
Values []*Value `protobuf:"bytes,1,rep,name=values" json:"values,omitempty"`
}
func (m *ListValue) Reset() { *m = ListValue{} }
func (m *ListValue) String() string { return proto.CompactTextString(m) }
func (*ListValue) ProtoMessage() {}
func (*ListValue) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (*ListValue) XXX_WellKnownType() string { return "ListValue" }
func (m *ListValue) GetValues() []*Value {
if m != nil {
return m.Values
}
return nil
}
func init() {
proto.RegisterType((*Struct)(nil), "google.protobuf.Struct")
proto.RegisterType((*Value)(nil), "google.protobuf.Value")
proto.RegisterType((*ListValue)(nil), "google.protobuf.ListValue")
proto.RegisterEnum("google.protobuf.NullValue", NullValue_name, NullValue_value)
}
func init() { proto.RegisterFile("google/protobuf/struct.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 417 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0x41, 0x8b, 0xd3, 0x40,
0x14, 0xc7, 0x3b, 0xc9, 0x36, 0x98, 0x17, 0x59, 0x97, 0x11, 0xb4, 0xac, 0xa2, 0xa1, 0x7b, 0x09,
0x22, 0x29, 0xd6, 0x8b, 0x18, 0x2f, 0x06, 0xd6, 0x5d, 0x30, 0x2c, 0x31, 0xba, 0x15, 0xbc, 0x94,
0x26, 0x4d, 0x63, 0xe8, 0x74, 0x26, 0x24, 0x33, 0x4a, 0x8f, 0x7e, 0x0b, 0xcf, 0x1e, 0x3d, 0xfa,
0xe9, 0x3c, 0xca, 0xcc, 0x24, 0xa9, 0xb4, 0xf4, 0x94, 0xbc, 0xf7, 0x7e, 0xef, 0x3f, 0xef, 0xff,
0x66, 0xe0, 0x71, 0xc1, 0x58, 0x41, 0xf2, 0x49, 0x55, 0x33, 0xce, 0x52, 0xb1, 0x9a, 0x34, 0xbc,
0x16, 0x19, 0xf7, 0x55, 0x8c, 0xef, 0xe9, 0xaa, 0xdf, 0x55, 0xc7, 0x3f, 0x11, 0x58, 0x1f, 0x15,
0x81, 0x03, 0xb0, 0x56, 0x65, 0x4e, 0x96, 0xcd, 0x08, 0xb9, 0xa6, 0xe7, 0x4c, 0x2f, 0xfc, 0x3d,
0xd8, 0xd7, 0xa0, 0xff, 0x4e, 0x51, 0x97, 0x94, 0xd7, 0xdb, 0xa4, 0x6d, 0x39, 0xff, 0x00, 0xce,
0x7f, 0x69, 0x7c, 0x06, 0xe6, 0x3a, 0xdf, 0x8e, 0x90, 0x8b, 0x3c, 0x3b, 0x91, 0xbf, 0xf8, 0x39,
0x0c, 0xbf, 0x2d, 0x88, 0xc8, 0x47, 0x86, 0x8b, 0x3c, 0x67, 0xfa, 0xe0, 0x40, 0x7c, 0x26, 0xab,
0x89, 0x86, 0x5e, 0x1b, 0xaf, 0xd0, 0xf8, 0x8f, 0x01, 0x43, 0x95, 0xc4, 0x01, 0x00, 0x15, 0x84,
0xcc, 0xb5, 0x80, 0x14, 0x3d, 0x9d, 0x9e, 0x1f, 0x08, 0xdc, 0x08, 0x42, 0x14, 0x7f, 0x3d, 0x48,
0x6c, 0xda, 0x05, 0xf8, 0x02, 0xee, 0x52, 0xb1, 0x49, 0xf3, 0x7a, 0xbe, 0x3b, 0x1f, 0x5d, 0x0f,
0x12, 0x47, 0x67, 0x7b, 0xa8, 0xe1, 0x75, 0x49, 0x8b, 0x16, 0x32, 0xe5, 0xe0, 0x12, 0xd2, 0x59,
0x0d, 0x3d, 0x05, 0x48, 0x19, 0xeb, 0xc6, 0x38, 0x71, 0x91, 0x77, 0x47, 0x1e, 0x25, 0x73, 0x1a,
0x78, 0xa3, 0x54, 0x44, 0xc6, 0x5b, 0x64, 0xa8, 0xac, 0x3e, 0x3c, 0xb2, 0xc7, 0x56, 0x5e, 0x64,
0xbc, 0x77, 0x49, 0xca, 0xa6, 0xeb, 0xb5, 0x54, 0xef, 0xa1, 0xcb, 0xa8, 0x6c, 0x78, 0xef, 0x92,
0x74, 0x41, 0x68, 0xc1, 0xc9, 0xba, 0xa4, 0xcb, 0x71, 0x00, 0x76, 0x4f, 0x60, 0x1f, 0x2c, 0x25,
0xd6, 0xdd, 0xe8, 0xb1, 0xa5, 0xb7, 0xd4, 0xb3, 0x47, 0x60, 0xf7, 0x4b, 0xc4, 0xa7, 0x00, 0x37,
0xb7, 0x51, 0x34, 0x9f, 0xbd, 0x8d, 0x6e, 0x2f, 0xcf, 0x06, 0xe1, 0x0f, 0x04, 0xf7, 0x33, 0xb6,
0xd9, 0x97, 0x08, 0x1d, 0xed, 0x26, 0x96, 0x71, 0x8c, 0xbe, 0xbc, 0x28, 0x4a, 0xfe, 0x55, 0xa4,
0x7e, 0xc6, 0x36, 0x93, 0x82, 0x91, 0x05, 0x2d, 0x76, 0x4f, 0xb1, 0xe2, 0xdb, 0x2a, 0x6f, 0xda,
0x17, 0x19, 0xe8, 0x4f, 0x95, 0xfe, 0x45, 0xe8, 0x97, 0x61, 0x5e, 0xc5, 0xe1, 0x6f, 0xe3, 0xc9,
0x95, 0x16, 0x8f, 0xbb, 0xf9, 0x3e, 0xe7, 0x84, 0xbc, 0xa7, 0xec, 0x3b, 0xfd, 0x24, 0x3b, 0x53,
0x4b, 0x49, 0xbd, 0xfc, 0x17, 0x00, 0x00, 0xff, 0xff, 0xe8, 0x1b, 0x59, 0xf8, 0xe5, 0x02, 0x00,
0x00,
}
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
syntax = "proto3";
package google.protobuf;
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option cc_enable_arenas = true;
option go_package = "github.com/golang/protobuf/ptypes/struct;structpb";
option java_package = "com.google.protobuf";
option java_outer_classname = "StructProto";
option java_multiple_files = true;
option objc_class_prefix = "GPB";
// `Struct` represents a structured data value, consisting of fields
// which map to dynamically typed values. In some languages, `Struct`
// might be supported by a native representation. For example, in
// scripting languages like JS a struct is represented as an
// object. The details of that representation are described together
// with the proto support for the language.
//
// The JSON representation for `Struct` is JSON object.
message Struct {
// Unordered 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.
//
// The JSON representation for `Value` is JSON value.
message Value {
// The kind of 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;
}
}
// `NullValue` is a singleton enumeration to represent the null value for the
// `Value` type union.
//
// The JSON representation for `NullValue` is JSON `null`.
enum NullValue {
// Null value.
NULL_VALUE = 0;
}
// `ListValue` is a wrapper around a repeated field of values.
//
// The JSON representation for `ListValue` is JSON array.
message ListValue {
// Repeated field of dynamically typed values.
repeated Value values = 1;
}
...@@ -57,6 +57,10 @@ It has these top-level messages: ...@@ -57,6 +57,10 @@ It has these top-level messages:
CommitDeltaResponse CommitDeltaResponse
CommitPatchRequest CommitPatchRequest
CommitPatchResponse CommitPatchResponse
RawDiffRequest
RawDiffResponse
RawPatchRequest
RawPatchResponse
AddNamespaceRequest AddNamespaceRequest
RemoveNamespaceRequest RemoveNamespaceRequest
RenameNamespaceRequest RenameNamespaceRequest
......
...@@ -382,6 +382,102 @@ func (m *CommitPatchResponse) GetData() []byte { ...@@ -382,6 +382,102 @@ func (m *CommitPatchResponse) GetData() []byte {
return nil return nil
} }
type RawDiffRequest struct {
Repository *Repository `protobuf:"bytes,1,opt,name=repository" json:"repository,omitempty"`
LeftCommitId string `protobuf:"bytes,2,opt,name=left_commit_id,json=leftCommitId" json:"left_commit_id,omitempty"`
RightCommitId string `protobuf:"bytes,3,opt,name=right_commit_id,json=rightCommitId" json:"right_commit_id,omitempty"`
}
func (m *RawDiffRequest) Reset() { *m = RawDiffRequest{} }
func (m *RawDiffRequest) String() string { return proto.CompactTextString(m) }
func (*RawDiffRequest) ProtoMessage() {}
func (*RawDiffRequest) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{7} }
func (m *RawDiffRequest) GetRepository() *Repository {
if m != nil {
return m.Repository
}
return nil
}
func (m *RawDiffRequest) GetLeftCommitId() string {
if m != nil {
return m.LeftCommitId
}
return ""
}
func (m *RawDiffRequest) GetRightCommitId() string {
if m != nil {
return m.RightCommitId
}
return ""
}
type RawDiffResponse struct {
Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
}
func (m *RawDiffResponse) Reset() { *m = RawDiffResponse{} }
func (m *RawDiffResponse) String() string { return proto.CompactTextString(m) }
func (*RawDiffResponse) ProtoMessage() {}
func (*RawDiffResponse) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{8} }
func (m *RawDiffResponse) GetData() []byte {
if m != nil {
return m.Data
}
return nil
}
type RawPatchRequest struct {
Repository *Repository `protobuf:"bytes,1,opt,name=repository" json:"repository,omitempty"`
LeftCommitId string `protobuf:"bytes,2,opt,name=left_commit_id,json=leftCommitId" json:"left_commit_id,omitempty"`
RightCommitId string `protobuf:"bytes,3,opt,name=right_commit_id,json=rightCommitId" json:"right_commit_id,omitempty"`
}
func (m *RawPatchRequest) Reset() { *m = RawPatchRequest{} }
func (m *RawPatchRequest) String() string { return proto.CompactTextString(m) }
func (*RawPatchRequest) ProtoMessage() {}
func (*RawPatchRequest) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{9} }
func (m *RawPatchRequest) GetRepository() *Repository {
if m != nil {
return m.Repository
}
return nil
}
func (m *RawPatchRequest) GetLeftCommitId() string {
if m != nil {
return m.LeftCommitId
}
return ""
}
func (m *RawPatchRequest) GetRightCommitId() string {
if m != nil {
return m.RightCommitId
}
return ""
}
type RawPatchResponse struct {
Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
}
func (m *RawPatchResponse) Reset() { *m = RawPatchResponse{} }
func (m *RawPatchResponse) String() string { return proto.CompactTextString(m) }
func (*RawPatchResponse) ProtoMessage() {}
func (*RawPatchResponse) Descriptor() ([]byte, []int) { return fileDescriptor3, []int{10} }
func (m *RawPatchResponse) GetData() []byte {
if m != nil {
return m.Data
}
return nil
}
func init() { func init() {
proto.RegisterType((*CommitDiffRequest)(nil), "gitaly.CommitDiffRequest") proto.RegisterType((*CommitDiffRequest)(nil), "gitaly.CommitDiffRequest")
proto.RegisterType((*CommitDiffResponse)(nil), "gitaly.CommitDiffResponse") proto.RegisterType((*CommitDiffResponse)(nil), "gitaly.CommitDiffResponse")
...@@ -390,6 +486,10 @@ func init() { ...@@ -390,6 +486,10 @@ func init() {
proto.RegisterType((*CommitDeltaResponse)(nil), "gitaly.CommitDeltaResponse") proto.RegisterType((*CommitDeltaResponse)(nil), "gitaly.CommitDeltaResponse")
proto.RegisterType((*CommitPatchRequest)(nil), "gitaly.CommitPatchRequest") proto.RegisterType((*CommitPatchRequest)(nil), "gitaly.CommitPatchRequest")
proto.RegisterType((*CommitPatchResponse)(nil), "gitaly.CommitPatchResponse") proto.RegisterType((*CommitPatchResponse)(nil), "gitaly.CommitPatchResponse")
proto.RegisterType((*RawDiffRequest)(nil), "gitaly.RawDiffRequest")
proto.RegisterType((*RawDiffResponse)(nil), "gitaly.RawDiffResponse")
proto.RegisterType((*RawPatchRequest)(nil), "gitaly.RawPatchRequest")
proto.RegisterType((*RawPatchResponse)(nil), "gitaly.RawPatchResponse")
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
...@@ -408,6 +508,8 @@ type DiffServiceClient interface { ...@@ -408,6 +508,8 @@ type DiffServiceClient interface {
// Return a stream so we can divide the response in chunks of deltas // Return a stream so we can divide the response in chunks of deltas
CommitDelta(ctx context.Context, in *CommitDeltaRequest, opts ...grpc.CallOption) (DiffService_CommitDeltaClient, error) CommitDelta(ctx context.Context, in *CommitDeltaRequest, opts ...grpc.CallOption) (DiffService_CommitDeltaClient, error)
CommitPatch(ctx context.Context, in *CommitPatchRequest, opts ...grpc.CallOption) (DiffService_CommitPatchClient, error) CommitPatch(ctx context.Context, in *CommitPatchRequest, opts ...grpc.CallOption) (DiffService_CommitPatchClient, error)
RawDiff(ctx context.Context, in *RawDiffRequest, opts ...grpc.CallOption) (DiffService_RawDiffClient, error)
RawPatch(ctx context.Context, in *RawPatchRequest, opts ...grpc.CallOption) (DiffService_RawPatchClient, error)
} }
type diffServiceClient struct { type diffServiceClient struct {
...@@ -514,6 +616,70 @@ func (x *diffServiceCommitPatchClient) Recv() (*CommitPatchResponse, error) { ...@@ -514,6 +616,70 @@ func (x *diffServiceCommitPatchClient) Recv() (*CommitPatchResponse, error) {
return m, nil return m, nil
} }
func (c *diffServiceClient) RawDiff(ctx context.Context, in *RawDiffRequest, opts ...grpc.CallOption) (DiffService_RawDiffClient, error) {
stream, err := grpc.NewClientStream(ctx, &_DiffService_serviceDesc.Streams[3], c.cc, "/gitaly.DiffService/RawDiff", opts...)
if err != nil {
return nil, err
}
x := &diffServiceRawDiffClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type DiffService_RawDiffClient interface {
Recv() (*RawDiffResponse, error)
grpc.ClientStream
}
type diffServiceRawDiffClient struct {
grpc.ClientStream
}
func (x *diffServiceRawDiffClient) Recv() (*RawDiffResponse, error) {
m := new(RawDiffResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
func (c *diffServiceClient) RawPatch(ctx context.Context, in *RawPatchRequest, opts ...grpc.CallOption) (DiffService_RawPatchClient, error) {
stream, err := grpc.NewClientStream(ctx, &_DiffService_serviceDesc.Streams[4], c.cc, "/gitaly.DiffService/RawPatch", opts...)
if err != nil {
return nil, err
}
x := &diffServiceRawPatchClient{stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
type DiffService_RawPatchClient interface {
Recv() (*RawPatchResponse, error)
grpc.ClientStream
}
type diffServiceRawPatchClient struct {
grpc.ClientStream
}
func (x *diffServiceRawPatchClient) Recv() (*RawPatchResponse, error) {
m := new(RawPatchResponse)
if err := x.ClientStream.RecvMsg(m); err != nil {
return nil, err
}
return m, nil
}
// Server API for DiffService service // Server API for DiffService service
type DiffServiceServer interface { type DiffServiceServer interface {
...@@ -522,6 +688,8 @@ type DiffServiceServer interface { ...@@ -522,6 +688,8 @@ type DiffServiceServer interface {
// Return a stream so we can divide the response in chunks of deltas // Return a stream so we can divide the response in chunks of deltas
CommitDelta(*CommitDeltaRequest, DiffService_CommitDeltaServer) error CommitDelta(*CommitDeltaRequest, DiffService_CommitDeltaServer) error
CommitPatch(*CommitPatchRequest, DiffService_CommitPatchServer) error CommitPatch(*CommitPatchRequest, DiffService_CommitPatchServer) error
RawDiff(*RawDiffRequest, DiffService_RawDiffServer) error
RawPatch(*RawPatchRequest, DiffService_RawPatchServer) error
} }
func RegisterDiffServiceServer(s *grpc.Server, srv DiffServiceServer) { func RegisterDiffServiceServer(s *grpc.Server, srv DiffServiceServer) {
...@@ -591,6 +759,48 @@ func (x *diffServiceCommitPatchServer) Send(m *CommitPatchResponse) error { ...@@ -591,6 +759,48 @@ func (x *diffServiceCommitPatchServer) Send(m *CommitPatchResponse) error {
return x.ServerStream.SendMsg(m) return x.ServerStream.SendMsg(m)
} }
func _DiffService_RawDiff_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(RawDiffRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(DiffServiceServer).RawDiff(m, &diffServiceRawDiffServer{stream})
}
type DiffService_RawDiffServer interface {
Send(*RawDiffResponse) error
grpc.ServerStream
}
type diffServiceRawDiffServer struct {
grpc.ServerStream
}
func (x *diffServiceRawDiffServer) Send(m *RawDiffResponse) error {
return x.ServerStream.SendMsg(m)
}
func _DiffService_RawPatch_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(RawPatchRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
return srv.(DiffServiceServer).RawPatch(m, &diffServiceRawPatchServer{stream})
}
type DiffService_RawPatchServer interface {
Send(*RawPatchResponse) error
grpc.ServerStream
}
type diffServiceRawPatchServer struct {
grpc.ServerStream
}
func (x *diffServiceRawPatchServer) Send(m *RawPatchResponse) error {
return x.ServerStream.SendMsg(m)
}
var _DiffService_serviceDesc = grpc.ServiceDesc{ var _DiffService_serviceDesc = grpc.ServiceDesc{
ServiceName: "gitaly.DiffService", ServiceName: "gitaly.DiffService",
HandlerType: (*DiffServiceServer)(nil), HandlerType: (*DiffServiceServer)(nil),
...@@ -611,6 +821,16 @@ var _DiffService_serviceDesc = grpc.ServiceDesc{ ...@@ -611,6 +821,16 @@ var _DiffService_serviceDesc = grpc.ServiceDesc{
Handler: _DiffService_CommitPatch_Handler, Handler: _DiffService_CommitPatch_Handler,
ServerStreams: true, ServerStreams: true,
}, },
{
StreamName: "RawDiff",
Handler: _DiffService_RawDiff_Handler,
ServerStreams: true,
},
{
StreamName: "RawPatch",
Handler: _DiffService_RawPatch_Handler,
ServerStreams: true,
},
}, },
Metadata: "diff.proto", Metadata: "diff.proto",
} }
...@@ -618,48 +838,53 @@ var _DiffService_serviceDesc = grpc.ServiceDesc{ ...@@ -618,48 +838,53 @@ var _DiffService_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("diff.proto", fileDescriptor3) } func init() { proto.RegisterFile("diff.proto", fileDescriptor3) }
var fileDescriptor3 = []byte{ var fileDescriptor3 = []byte{
// 679 bytes of a gzipped FileDescriptorProto // 753 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x55, 0xc1, 0x6e, 0xdb, 0x38, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x56, 0x4d, 0x6f, 0xdb, 0x46,
0x10, 0x5d, 0xc5, 0xb6, 0x22, 0x8f, 0x95, 0x64, 0x97, 0x59, 0x64, 0x15, 0x67, 0x0f, 0x86, 0xb0, 0x10, 0x2d, 0xf5, 0x41, 0x51, 0x23, 0x5a, 0x76, 0xd7, 0x85, 0x4d, 0xcb, 0x3d, 0x08, 0x44, 0xed,
0xdb, 0xba, 0x28, 0x10, 0x14, 0xee, 0xa5, 0xe7, 0x24, 0x68, 0x91, 0x20, 0x41, 0x03, 0xf5, 0xd0, 0xaa, 0x28, 0x60, 0x14, 0xea, 0xa5, 0xa7, 0x02, 0xb5, 0x8d, 0x16, 0x36, 0x6c, 0xd4, 0x60, 0x0e,
0xa3, 0xc0, 0x98, 0x23, 0x9b, 0xa8, 0x24, 0xba, 0x24, 0x1b, 0xc7, 0x5f, 0xd4, 0x4b, 0xff, 0xa8, 0x39, 0x12, 0x6b, 0xed, 0x52, 0x5a, 0x84, 0xe4, 0x2a, 0xbb, 0x1b, 0xcb, 0xfa, 0x1b, 0xc9, 0x8f,
0xff, 0xd0, 0x2f, 0xe8, 0xa1, 0x20, 0x29, 0xc9, 0x72, 0xe0, 0x5b, 0x2f, 0xb9, 0x79, 0xde, 0x7b, 0xc8, 0x25, 0xff, 0x28, 0xbf, 0x22, 0xf7, 0x1c, 0x82, 0xdd, 0x25, 0x29, 0xca, 0x56, 0x72, 0x71,
0x9e, 0x21, 0xdf, 0xe3, 0xd8, 0x00, 0x8c, 0x67, 0xd9, 0xe9, 0x42, 0x0a, 0x2d, 0x88, 0x3f, 0xe3, 0x0e, 0xbe, 0x69, 0xdf, 0x7b, 0x9c, 0x19, 0xbe, 0x37, 0x4b, 0x08, 0x80, 0xb0, 0x24, 0x39, 0x99,
0x9a, 0xe6, 0xab, 0x61, 0xa8, 0xe6, 0x54, 0x22, 0x73, 0x68, 0xfc, 0xb3, 0x03, 0x7f, 0x9d, 0x8b, 0x0b, 0xae, 0x38, 0x72, 0xa7, 0x4c, 0xe1, 0x74, 0x39, 0xf0, 0xe5, 0x0c, 0x0b, 0x4a, 0x2c, 0x1a,
0xa2, 0xe0, 0xfa, 0x82, 0x67, 0x59, 0x82, 0x9f, 0xbf, 0xa0, 0xd2, 0x64, 0x02, 0x20, 0x71, 0x21, 0x7e, 0x6e, 0xc2, 0x8f, 0x67, 0x3c, 0xcb, 0x98, 0x3a, 0x67, 0x49, 0x12, 0xd1, 0xd7, 0x6f, 0xa8,
0x14, 0xd7, 0x42, 0xae, 0x22, 0x6f, 0xe4, 0x8d, 0x07, 0x13, 0x72, 0xea, 0x1a, 0x9c, 0x26, 0x0d, 0x54, 0x68, 0x0c, 0x20, 0xe8, 0x9c, 0x4b, 0xa6, 0xb8, 0x58, 0x06, 0xce, 0xd0, 0x19, 0xf5, 0xc6,
0x93, 0xb4, 0x54, 0xe4, 0x3f, 0xd8, 0xcf, 0x31, 0xd3, 0xe9, 0xd4, 0x76, 0x4b, 0x39, 0x8b, 0x76, 0xe8, 0xc4, 0x16, 0x38, 0x89, 0x2a, 0x26, 0xaa, 0xa9, 0xd0, 0x2f, 0xd0, 0x4f, 0x69, 0xa2, 0xe2,
0x46, 0xde, 0xb8, 0x9f, 0x84, 0x06, 0x75, 0x23, 0x2e, 0x19, 0x79, 0x06, 0x07, 0x92, 0xcf, 0xe6, 0x89, 0xa9, 0x16, 0x33, 0x12, 0x34, 0x86, 0xce, 0xa8, 0x1b, 0xf9, 0x1a, 0xb5, 0x2d, 0x2e, 0x08,
0x6d, 0x59, 0xc7, 0xca, 0xf6, 0x2c, 0xdc, 0xe8, 0xde, 0x40, 0xc4, 0x67, 0xa5, 0x90, 0x98, 0x2e, 0x3a, 0x86, 0x6d, 0xc1, 0xa6, 0xb3, 0xba, 0xac, 0x69, 0x64, 0x5b, 0x06, 0xae, 0x74, 0x7f, 0x41,
0xe7, 0x5c, 0xa3, 0x5a, 0xd0, 0x29, 0xa6, 0xd3, 0x39, 0x2d, 0x67, 0x18, 0x75, 0x47, 0xde, 0x38, 0xc0, 0xa6, 0x39, 0x17, 0x34, 0x5e, 0xcc, 0x98, 0xa2, 0x72, 0x8e, 0x27, 0x34, 0x9e, 0xcc, 0x70,
0x48, 0x8e, 0x1c, 0xff, 0xb1, 0xa1, 0xcf, 0x2d, 0x4b, 0xfe, 0x86, 0xde, 0x82, 0xea, 0xb9, 0x8a, 0x3e, 0xa5, 0x41, 0x6b, 0xe8, 0x8c, 0xbc, 0x68, 0xcf, 0xf2, 0x2f, 0x2b, 0xfa, 0xcc, 0xb0, 0xe8,
0x7a, 0xa3, 0xce, 0x38, 0x4c, 0x5c, 0x41, 0xfe, 0x87, 0xfd, 0xa9, 0xc8, 0x73, 0xba, 0x50, 0x98, 0x27, 0x68, 0xcf, 0xb1, 0x9a, 0xc9, 0xa0, 0x3d, 0x6c, 0x8e, 0xfc, 0xc8, 0x1e, 0xd0, 0x11, 0xf4,
0x1a, 0x53, 0x54, 0xe4, 0xdb, 0x2e, 0x7b, 0x35, 0x6a, 0xae, 0x6f, 0x65, 0x58, 0x66, 0x42, 0x4e, 0x27, 0x3c, 0x4d, 0xf1, 0x5c, 0xd2, 0x58, 0x9b, 0x22, 0x03, 0xd7, 0x54, 0xd9, 0x2a, 0x51, 0xfd,
0x31, 0xcd, 0x79, 0xc1, 0xb5, 0x8a, 0x76, 0x9d, 0xac, 0x42, 0xaf, 0x2d, 0x48, 0x4e, 0xa0, 0x5f, 0xfa, 0x46, 0x46, 0xf3, 0x84, 0x8b, 0x09, 0x8d, 0x53, 0x96, 0x31, 0x25, 0x83, 0x8e, 0x95, 0x15,
0xd0, 0x87, 0x34, 0xe3, 0x39, 0xaa, 0x28, 0x18, 0x79, 0xe3, 0x5e, 0x12, 0x14, 0xf4, 0xe1, 0xad, 0xe8, 0x95, 0x01, 0xd1, 0x21, 0x74, 0x33, 0x7c, 0x1f, 0x27, 0x2c, 0xa5, 0x32, 0xf0, 0x86, 0xce,
0xa9, 0x6b, 0x32, 0xe7, 0x25, 0xaa, 0xa8, 0xdf, 0x90, 0xd7, 0xa6, 0xae, 0xc9, 0xbb, 0x95, 0x46, 0xa8, 0x1d, 0x79, 0x19, 0xbe, 0xff, 0x57, 0x9f, 0x4b, 0x32, 0x65, 0x39, 0x95, 0x41, 0xb7, 0x22,
0x15, 0x41, 0x43, 0x9e, 0x99, 0xda, 0x58, 0xa8, 0x68, 0x86, 0xe9, 0xba, 0xf7, 0xc0, 0x2a, 0x42, 0xaf, 0xf4, 0xb9, 0x24, 0x6f, 0x97, 0x8a, 0xca, 0x00, 0x2a, 0xf2, 0x54, 0x9f, 0xb5, 0x85, 0x12,
0x83, 0xde, 0xd4, 0xfd, 0xdb, 0x2a, 0x37, 0x24, 0xdc, 0x50, 0xb9, 0x41, 0x6d, 0x95, 0x9b, 0xb6, 0x27, 0x34, 0x5e, 0xd5, 0xee, 0x19, 0x85, 0xaf, 0xd1, 0xeb, 0xb2, 0x7e, 0x5d, 0x65, 0x9b, 0xf8,
0xb7, 0xa1, 0xb2, 0x13, 0xe3, 0xef, 0x3b, 0x40, 0xda, 0xf1, 0xab, 0x85, 0x28, 0x15, 0x9a, 0x53, 0x6b, 0x2a, 0xdb, 0xa8, 0xae, 0xb2, 0xdd, 0xb6, 0xd6, 0x54, 0xa6, 0x63, 0xf8, 0xb1, 0x01, 0xa8,
0x66, 0x52, 0x14, 0xa9, 0xf1, 0xce, 0xc6, 0x1f, 0x26, 0x81, 0x01, 0x6e, 0xa9, 0x9e, 0x93, 0x7f, 0x1e, 0xbf, 0x9c, 0xf3, 0x5c, 0x52, 0x3d, 0x65, 0x22, 0x78, 0x16, 0x6b, 0xef, 0x4c, 0xfc, 0x7e,
0x60, 0x57, 0x0b, 0x47, 0xed, 0x58, 0xca, 0xd7, 0xa2, 0x26, 0xec, 0xb7, 0x9a, 0x4c, 0x7d, 0x53, 0xe4, 0x69, 0xe0, 0x06, 0xab, 0x19, 0xda, 0x87, 0x8e, 0xe2, 0x96, 0x6a, 0x18, 0xca, 0x55, 0xbc,
0x5e, 0x32, 0x72, 0x08, 0x3d, 0x2d, 0x0c, 0xdc, 0xb5, 0x70, 0x57, 0x8b, 0x4b, 0x46, 0x8e, 0x21, 0x24, 0xcc, 0x53, 0x55, 0xa6, 0xae, 0x3e, 0x5e, 0x10, 0xb4, 0x0b, 0x6d, 0xc5, 0x35, 0xdc, 0x32,
0x10, 0x39, 0x4b, 0x0b, 0xc1, 0x30, 0xea, 0xd9, 0xa3, 0xed, 0x8a, 0x9c, 0xdd, 0x08, 0x86, 0x86, 0x70, 0x4b, 0xf1, 0x0b, 0x82, 0x0e, 0xc0, 0xe3, 0x29, 0x89, 0x33, 0x4e, 0x68, 0xd0, 0x36, 0xa3,
0x2a, 0x71, 0xe9, 0x28, 0xdf, 0x51, 0x25, 0x2e, 0x2d, 0x75, 0x04, 0xfe, 0x1d, 0x2f, 0xa9, 0x5c, 0x75, 0x78, 0x4a, 0xae, 0x39, 0xa1, 0x9a, 0xca, 0xe9, 0xc2, 0x52, 0xae, 0xa5, 0x72, 0xba, 0x30,
0x55, 0xc1, 0x54, 0x95, 0xb9, 0xae, 0xa4, 0x4b, 0x73, 0xaa, 0xe9, 0x3c, 0x65, 0x54, 0x53, 0xeb, 0xd4, 0x1e, 0xb8, 0xb7, 0x2c, 0xc7, 0x62, 0x59, 0x04, 0x53, 0x9c, 0xf4, 0xeb, 0x0a, 0xbc, 0xd0,
0x7c, 0x98, 0x84, 0x92, 0x2e, 0x6f, 0x0d, 0x78, 0x41, 0x35, 0x25, 0x23, 0x08, 0xb1, 0x64, 0xa9, 0x53, 0x4d, 0x66, 0x31, 0xc1, 0x0a, 0x1b, 0xe7, 0xfd, 0xc8, 0x17, 0x78, 0x71, 0xa3, 0xc1, 0x73,
0xc8, 0x9c, 0xd0, 0x06, 0x10, 0x24, 0x80, 0x25, 0x7b, 0x9f, 0x59, 0x15, 0x79, 0x0e, 0x07, 0xe2, 0xac, 0x30, 0x1a, 0x82, 0x4f, 0x73, 0x12, 0xf3, 0xc4, 0x0a, 0x4d, 0x00, 0x5e, 0x04, 0x34, 0x27,
0x1e, 0x65, 0x96, 0x8b, 0x65, 0x5a, 0x50, 0xf9, 0x09, 0xa5, 0xcd, 0x20, 0x48, 0xf6, 0x6b, 0xf8, 0xff, 0x27, 0x46, 0x85, 0x7e, 0x85, 0x6d, 0x7e, 0x47, 0x45, 0x92, 0xf2, 0x45, 0x9c, 0x61, 0xf1,
0xc6, 0xa2, 0xe4, 0x5f, 0xe8, 0xd7, 0x4f, 0x87, 0xd9, 0x00, 0x82, 0x64, 0x0d, 0x5c, 0x75, 0x83, 0x8a, 0x0a, 0x93, 0x81, 0x17, 0xf5, 0x4b, 0xf8, 0xda, 0xa0, 0xe8, 0x67, 0xe8, 0x96, 0xab, 0x43,
0xe0, 0xcf, 0x7e, 0xfc, 0xcd, 0x6b, 0xdc, 0xc5, 0x5c, 0xd3, 0xa7, 0xb3, 0x5d, 0xcd, 0x8e, 0x74, 0x4c, 0x00, 0x5e, 0xb4, 0x02, 0x2e, 0x5b, 0x9e, 0xb7, 0xd3, 0x0d, 0x3f, 0x38, 0x95, 0xbb, 0x34,
0x5b, 0x3b, 0x12, 0x7f, 0xf5, 0x60, 0xd0, 0x3a, 0xee, 0xd3, 0x7d, 0x05, 0xf1, 0x19, 0x1c, 0x6e, 0x55, 0xf8, 0xf9, 0xdc, 0xae, 0xea, 0x8e, 0xb4, 0x6a, 0x77, 0x24, 0x7c, 0xef, 0x40, 0xaf, 0x36,
0xf8, 0x5a, 0x3d, 0xdb, 0x97, 0xe0, 0x33, 0x03, 0xa8, 0xc8, 0x1b, 0x75, 0xc6, 0x83, 0xc9, 0x61, 0xee, 0xf3, 0xdd, 0x82, 0xf0, 0x14, 0x76, 0xd7, 0x7c, 0x2d, 0xd6, 0xf6, 0x77, 0x70, 0x89, 0x06,
0x6d, 0x6a, 0x5b, 0x5c, 0x49, 0x62, 0x56, 0x67, 0x63, 0x83, 0xff, 0x9d, 0x6c, 0x86, 0x10, 0x48, 0x64, 0xe0, 0x0c, 0x9b, 0xa3, 0xde, 0x78, 0xb7, 0x34, 0xb5, 0x2e, 0x2e, 0x24, 0x21, 0x29, 0xb3,
0xbc, 0xe7, 0x8a, 0x8b, 0xb2, 0xf2, 0xa2, 0xa9, 0xe3, 0x17, 0xf5, 0x49, 0xab, 0x29, 0xd5, 0x49, 0x31, 0xc1, 0x3f, 0x25, 0x9b, 0x01, 0x78, 0x82, 0xde, 0x31, 0xc9, 0x78, 0x5e, 0x78, 0x51, 0x9d,
0x09, 0x74, 0xed, 0x23, 0x75, 0xae, 0xda, 0xcf, 0x93, 0x1f, 0x1e, 0x0c, 0xcc, 0x16, 0x7e, 0x40, 0xc3, 0xdf, 0xca, 0x49, 0x8b, 0x2e, 0xc5, 0xa4, 0x08, 0x5a, 0x66, 0x49, 0xad, 0xab, 0xe6, 0x77,
0x79, 0xcf, 0xa7, 0x48, 0xde, 0x01, 0xac, 0x57, 0x93, 0x1c, 0x3f, 0xba, 0xcb, 0xfa, 0xd7, 0x7a, 0xf8, 0xd6, 0x81, 0x7e, 0x84, 0x17, 0xcf, 0xea, 0x3b, 0x1c, 0x1e, 0xc1, 0x76, 0x35, 0xd3, 0x37,
0x38, 0xdc, 0x46, 0xb9, 0x41, 0xf1, 0x1f, 0xaf, 0x3c, 0x72, 0xb5, 0x19, 0xeb, 0x70, 0x9b, 0x2b, 0x66, 0x7f, 0xe7, 0x18, 0xdd, 0x93, 0xad, 0xfc, 0xbe, 0xc3, 0x1f, 0xc3, 0xce, 0x6a, 0xa8, 0xaf,
0x55, 0xab, 0x93, 0xad, 0xdc, 0xb6, 0x5e, 0x6e, 0x5d, 0x1e, 0xf5, 0x6a, 0x5b, 0xf9, 0xb8, 0xd7, 0x4f, 0x3f, 0xfe, 0xd4, 0x80, 0x9e, 0x7e, 0xc5, 0x17, 0x54, 0xdc, 0xb1, 0x09, 0x45, 0xff, 0x01,
0x86, 0x01, 0xa6, 0xd7, 0x9d, 0x6f, 0xff, 0x82, 0x5e, 0xff, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x15, 0xac, 0x3e, 0x8a, 0xe8, 0xe0, 0xc1, 0x16, 0xad, 0xf2, 0x19, 0x0c, 0x36, 0x51, 0xb6, 0x51, 0xf8,
0xae, 0x47, 0xd4, 0xa6, 0x06, 0x00, 0x00, 0xc3, 0x1f, 0x0e, 0xba, 0x5c, 0xbf, 0x50, 0x83, 0x4d, 0xfb, 0x58, 0x94, 0x3a, 0xdc, 0xc8, 0x6d,
0xaa, 0x65, 0x3f, 0x54, 0x0f, 0x6a, 0xd5, 0x9d, 0x7f, 0x58, 0x6b, 0xcd, 0x00, 0x53, 0xeb, 0x6f,
0xe8, 0x14, 0xa9, 0xa2, 0xbd, 0x2a, 0x91, 0xb5, 0xd5, 0x1b, 0xec, 0x3f, 0xc2, 0x6b, 0xcf, 0xff,
0x03, 0x5e, 0x69, 0x2c, 0xaa, 0x0b, 0xd7, 0xa6, 0x08, 0x1e, 0x13, 0xab, 0x12, 0xb7, 0xae, 0xf9,
0xff, 0xf1, 0xe7, 0x97, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0x7c, 0x0d, 0x4f, 0xa3, 0x08, 0x00,
0x00,
} }
...@@ -42,11 +42,23 @@ ...@@ -42,11 +42,23 @@
"path": "github.com/getsentry/raven-go", "path": "github.com/getsentry/raven-go",
"revision": "379f8d0a68ca237cf8893a1cdfd4f574125e2c51" "revision": "379f8d0a68ca237cf8893a1cdfd4f574125e2c51"
}, },
{
"checksumSHA1": "eG45Hg4ZnB4b1KuqsMknc5eAx4A=",
"path": "github.com/golang/protobuf/jsonpb",
"revision": "130e6b02ab059e7b717a096f397c5b60111cae74",
"revisionTime": "2017-09-20T22:06:47Z"
},
{ {
"checksumSHA1": "kBeNcaKk56FguvPSUCEaH6AxpRc=", "checksumSHA1": "kBeNcaKk56FguvPSUCEaH6AxpRc=",
"path": "github.com/golang/protobuf/proto", "path": "github.com/golang/protobuf/proto",
"revision": "8ee79997227bf9b34611aee7946ae64735e6fd93" "revision": "8ee79997227bf9b34611aee7946ae64735e6fd93"
}, },
{
"checksumSHA1": "Ylq6kq3KWBy6mu68oyEwenhNMdg=",
"path": "github.com/golang/protobuf/ptypes/struct",
"revision": "130e6b02ab059e7b717a096f397c5b60111cae74",
"revisionTime": "2017-09-20T22:06:47Z"
},
{ {
"checksumSHA1": "sfoot+dHmmOgWZS6GJ5X79ClZM0=", "checksumSHA1": "sfoot+dHmmOgWZS6GJ5X79ClZM0=",
"path": "github.com/golang/protobuf/ptypes/timestamp", "path": "github.com/golang/protobuf/ptypes/timestamp",
...@@ -152,12 +164,12 @@ ...@@ -152,12 +164,12 @@
"revisionTime": "2016-11-17T07:43:51Z" "revisionTime": "2016-11-17T07:43:51Z"
}, },
{ {
"checksumSHA1": "tisAil16tojFqhqWYbs2kXwBYyk=", "checksumSHA1": "I7Kz+IncdenJ5tOCo/5qJlQ4U7k=",
"path": "gitlab.com/gitlab-org/gitaly-proto/go", "path": "gitlab.com/gitlab-org/gitaly-proto/go",
"revision": "12872bd8dad9dc72328b2c590386e67a17c65612", "revision": "8ac6c4c6cb2c124ff95cdd0f97bc4624055edc8f",
"revisionTime": "2017-09-27T21:53:01Z", "revisionTime": "2017-10-02T18:55:11Z",
"version": "v0.38.0", "version": "v0.39.0",
"versionExact": "v0.38.0" "versionExact": "v0.39.0"
}, },
{ {
"checksumSHA1": "dUHJbKas746n5fLzlwxHb6FOCxs=", "checksumSHA1": "dUHJbKas746n5fLzlwxHb6FOCxs=",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment