diff --git a/go.mod b/go.mod index 4be4397e..c5259e77 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,8 @@ module github.com/chapar-rest/chapar go 1.22.1 require ( - gioui.org v0.6.0 - gioui.org/x v0.6.1 + gioui.org v0.7.0 + gioui.org/x v0.7.0 github.com/PaesslerAG/jsonpath v0.1.1 github.com/dustin/go-humanize v1.0.1 github.com/google/uuid v1.6.0 diff --git a/go.sum b/go.sum index 5f50f8f8..ddd4242e 100644 --- a/go.sum +++ b/go.sum @@ -1,14 +1,14 @@ eliasnaur.com/font v0.0.0-20230308162249-dd43949cb42d h1:ARo7NCVvN2NdhLlJE9xAbKweuI9L6UgfTbYb0YwPacY= eliasnaur.com/font v0.0.0-20230308162249-dd43949cb42d/go.mod h1:OYVuxibdk9OSLX8vAqydtRPP87PyTFcT9uH3MlEGBQA= -gioui.org v0.6.0 h1:ZSXO/AbpFZJ2L9NU69uFQfDI3BKIH+YEJElrn0B+aZI= -gioui.org v0.6.0/go.mod h1:eUvGo6FAzA7jUqeSu5a+M1W03yc9r1nanIBS8A5+Nng= +gioui.org v0.7.0 h1:5I+7Uu2yjTu7W5p7HWQrgsDPO3vex+8T1DsvCLGBfuI= +gioui.org v0.7.0/go.mod h1:19wZxaNP+eHN4H2YdZwEfbkAAgoYB5rcIbDHo4BqUl4= gioui.org/cpu v0.0.0-20210808092351-bfe733dd3334/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ= gioui.org/cpu v0.0.0-20220412190645-f1e9e8c3b1f7 h1:tNJdnP5CgM39PRc+KWmBRRYX/zJ+rd5XaYxY5d5veqA= gioui.org/cpu v0.0.0-20220412190645-f1e9e8c3b1f7/go.mod h1:A8M0Cn5o+vY5LTMlnRoK3O5kG+rH0kWfJjeKd9QpBmQ= gioui.org/shader v1.0.8 h1:6ks0o/A+b0ne7RzEqRZK5f4Gboz2CfG+mVliciy6+qA= gioui.org/shader v1.0.8/go.mod h1:mWdiME581d/kV7/iEhLmUgUK5iZ09XR5XpduXzbePVM= -gioui.org/x v0.6.1 h1:cHxT3CA07YYm6yNv6FrHRUqbNH2KId8vli3uIM8BF5A= -gioui.org/x v0.6.1/go.mod h1:18BNyA2swIgDWV3/Nf7cQh9TaCTQQGbdLUg+pmURS3o= +gioui.org/x v0.7.0 h1:8rkLfy4MAHM+MgEv8IUwRcmB9rxJqYnRzbuOJqXzG6Y= +gioui.org/x v0.7.0/go.mod h1:zJdmUbD5PuGHL8fzX0kehLTZ6TmIvfo6mg10sW54dsU= git.wow.st/gmp/jni v0.0.0-20210610011705-34026c7e22d0 h1:bGG/g4ypjrCJoSvFrP5hafr9PPB5aw8SjcOWWila7ZI= git.wow.st/gmp/jni v0.0.0-20210610011705-34026c7e22d0/go.mod h1:+axXBRUTIDlCeE73IKeD/os7LoEnTKdkp8/gQOFjqyo= github.com/PaesslerAG/gval v1.0.0/go.mod h1:y/nm5yEyTeX6av0OfKJNp9rBNj2XrGhAf5+v24IBN1I= diff --git a/vendor/gioui.org/app/egl_android.go b/vendor/gioui.org/app/egl_android.go index 4d8352e7..f1db93ab 100644 --- a/vendor/gioui.org/app/egl_android.go +++ b/vendor/gioui.org/app/egl_android.go @@ -17,9 +17,8 @@ import ( ) type androidContext struct { - win *window - eglSurf egl.NativeWindowType - width, height int + win *window + eglSurf egl.NativeWindowType *egl.Context } @@ -45,9 +44,8 @@ func (c *androidContext) Refresh() error { if err := c.win.setVisual(c.Context.VisualID()); err != nil { return err } - win, width, height := c.win.nativeWindow() + win, _, _ := c.win.nativeWindow() c.eglSurf = egl.NativeWindowType(unsafe.Pointer(win)) - c.width, c.height = width, height return nil } @@ -55,7 +53,7 @@ func (c *androidContext) Lock() error { // The Android emulator creates a broken surface if it is not // created on the same thread as the context is made current. if c.eglSurf != nil { - if err := c.Context.CreateSurface(c.eglSurf, c.width, c.height); err != nil { + if err := c.Context.CreateSurface(c.eglSurf); err != nil { return err } c.eglSurf = nil diff --git a/vendor/gioui.org/app/egl_wayland.go b/vendor/gioui.org/app/egl_wayland.go index 04aa60d8..52a883eb 100644 --- a/vendor/gioui.org/app/egl_wayland.go +++ b/vendor/gioui.org/app/egl_wayland.go @@ -69,7 +69,7 @@ func (c *wlContext) Refresh() error { } c.eglWin = eglWin eglSurf := egl.NativeWindowType(uintptr(unsafe.Pointer(eglWin))) - if err := c.Context.CreateSurface(eglSurf, width, height); err != nil { + if err := c.Context.CreateSurface(eglSurf); err != nil { return err } if err := c.Context.MakeCurrent(); err != nil { diff --git a/vendor/gioui.org/app/egl_windows.go b/vendor/gioui.org/app/egl_windows.go index f4d994ad..0522a792 100644 --- a/vendor/gioui.org/app/egl_windows.go +++ b/vendor/gioui.org/app/egl_windows.go @@ -5,8 +5,6 @@ package app import ( - "golang.org/x/sys/windows" - "gioui.org/internal/egl" ) @@ -24,6 +22,18 @@ func init() { if err != nil { return nil, err } + win, _, _ := w.HWND() + eglSurf := egl.NativeWindowType(win) + if err := ctx.CreateSurface(eglSurf); err != nil { + ctx.Release() + return nil, err + } + if err := ctx.MakeCurrent(); err != nil { + ctx.Release() + return nil, err + } + defer ctx.ReleaseCurrent() + ctx.EnableVSync(true) return &glContext{win: w, Context: ctx}, nil }, }) @@ -37,21 +47,6 @@ func (c *glContext) Release() { } func (c *glContext) Refresh() error { - c.Context.ReleaseSurface() - var ( - win windows.Handle - width, height int - ) - win, width, height = c.win.HWND() - eglSurf := egl.NativeWindowType(win) - if err := c.Context.CreateSurface(eglSurf, width, height); err != nil { - return err - } - if err := c.Context.MakeCurrent(); err != nil { - return err - } - c.Context.EnableVSync(true) - c.Context.ReleaseCurrent() return nil } diff --git a/vendor/gioui.org/app/egl_x11.go b/vendor/gioui.org/app/egl_x11.go index c60f06de..b10b2581 100644 --- a/vendor/gioui.org/app/egl_x11.go +++ b/vendor/gioui.org/app/egl_x11.go @@ -25,6 +25,18 @@ func init() { if err != nil { return nil, err } + win, _, _ := w.window() + eglSurf := egl.NativeWindowType(uintptr(win)) + if err := ctx.CreateSurface(eglSurf); err != nil { + ctx.Release() + return nil, err + } + if err := ctx.MakeCurrent(); err != nil { + ctx.Release() + return nil, err + } + defer ctx.ReleaseCurrent() + ctx.EnableVSync(true) return &x11Context{win: w, Context: ctx}, nil } } @@ -37,17 +49,6 @@ func (c *x11Context) Release() { } func (c *x11Context) Refresh() error { - c.Context.ReleaseSurface() - win, width, height := c.win.window() - eglSurf := egl.NativeWindowType(uintptr(win)) - if err := c.Context.CreateSurface(eglSurf, width, height); err != nil { - return err - } - if err := c.Context.MakeCurrent(); err != nil { - return err - } - defer c.Context.ReleaseCurrent() - c.Context.EnableVSync(true) return nil } diff --git a/vendor/gioui.org/app/os.go b/vendor/gioui.org/app/os.go index 36a01034..e1ded757 100644 --- a/vendor/gioui.org/app/os.go +++ b/vendor/gioui.org/app/os.go @@ -176,7 +176,7 @@ type context interface { // basicDriver is the subset of [driver] that may be called even after // a window is destroyed. type basicDriver interface { - // Event blocks until an even is available and returns it. + // Event blocks until an event is available and returns it. Event() event.Event // Invalidate requests a FrameEvent. Invalidate() diff --git a/vendor/gioui.org/app/os_darwin.go b/vendor/gioui.org/app/os_darwin.go index 8f82cc94..fc5a4353 100644 --- a/vendor/gioui.org/app/os_darwin.go +++ b/vendor/gioui.org/app/os_darwin.go @@ -75,9 +75,13 @@ var displayLinks sync.Map var mainFuncs = make(chan func(), 1) +func isMainThread() bool { + return bool(C.isMainThread()) +} + // runOnMain runs the function on the main thread. func runOnMain(f func()) { - if C.isMainThread() { + if isMainThread() { f() return } diff --git a/vendor/gioui.org/app/os_ios.go b/vendor/gioui.org/app/os_ios.go index 3da86071..53a22eaf 100644 --- a/vendor/gioui.org/app/os_ios.go +++ b/vendor/gioui.org/app/os_ios.go @@ -12,6 +12,7 @@ package app #include #include +__attribute__ ((visibility ("hidden"))) int gio_applicationMain(int argc, char *argv[]); __attribute__ ((visibility ("hidden"))) void gio_viewSetHandle(CFTypeRef viewRef, uintptr_t handle); struct drawParams { @@ -81,6 +82,7 @@ import "C" import ( "image" "io" + "os" "runtime" "runtime/cgo" "runtime/debug" @@ -394,12 +396,47 @@ func newWindow(win *callbacks, options []Option) { <-mainWindow.windows } +var mainMode = mainModeUndefined + +const ( + mainModeUndefined = iota + mainModeExe + mainModeLibrary +) + func osMain() { + if !isMainThread() { + panic("app.Main must be run on the main goroutine") + } + switch mainMode { + case mainModeUndefined: + mainMode = mainModeExe + var argv []*C.char + for _, arg := range os.Args { + a := C.CString(arg) + defer C.free(unsafe.Pointer(a)) + argv = append(argv, a) + } + C.gio_applicationMain(C.int(len(argv)), unsafe.SliceData(argv)) + case mainModeExe: + panic("app.Main may be called only once") + case mainModeLibrary: + // Do nothing, we're embedded as a library. + } } //export gio_runMain func gio_runMain() { - runMain() + if !isMainThread() { + panic("app.Main must be run on the main goroutine") + } + switch mainMode { + case mainModeUndefined: + mainMode = mainModeLibrary + runMain() + case mainModeExe: + // Do nothing, main has already been called. + } } func (UIKitViewEvent) implementsViewEvent() {} diff --git a/vendor/gioui.org/app/os_ios.m b/vendor/gioui.org/app/os_ios.m index de57aaa5..bea50690 100644 --- a/vendor/gioui.org/app/os_ios.m +++ b/vendor/gioui.org/app/os_ios.m @@ -280,3 +280,23 @@ void gio_viewSetHandle(CFTypeRef viewRef, uintptr_t handle) { GioView *v = (__bridge GioView *)viewRef; v.handle = handle; } + +@interface _gioAppDelegate : UIResponder +@property (strong, nonatomic) UIWindow *window; +@end + +@implementation _gioAppDelegate +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + GioViewController *controller = [[GioViewController alloc] initWithNibName:nil bundle:nil]; + self.window.rootViewController = controller; + [self.window makeKeyAndVisible]; + return YES; +} +@end + +int gio_applicationMain(int argc, char *argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([_gioAppDelegate class])); + } +} diff --git a/vendor/gioui.org/app/os_macos.go b/vendor/gioui.org/app/os_macos.go index cb27f942..1da5083f 100644 --- a/vendor/gioui.org/app/os_macos.go +++ b/vendor/gioui.org/app/os_macos.go @@ -976,6 +976,9 @@ func (w *window) init() error { } func osMain() { + if !isMainThread() { + panic("app.Main must run on the main goroutine") + } C.gio_main() } diff --git a/vendor/gioui.org/app/os_macos.m b/vendor/gioui.org/app/os_macos.m index 0a3f6262..01b42978 100644 --- a/vendor/gioui.org/app/os_macos.m +++ b/vendor/gioui.org/app/os_macos.m @@ -47,13 +47,17 @@ - (void)windowDidChangeScreen:(NSNotification *)notification { } - (void)windowDidBecomeKey:(NSNotification *)notification { NSWindow *window = (NSWindow *)[notification object]; - GioView *view = (GioView *)window.contentView; - gio_onFocus(view.handle, 1); + GioView *view = (GioView *)window.contentView; + if ([window firstResponder] == view) { + gio_onFocus(view.handle, 1); + } } - (void)windowDidResignKey:(NSNotification *)notification { NSWindow *window = (NSWindow *)[notification object]; - GioView *view = (GioView *)window.contentView; - gio_onFocus(view.handle, 0); + GioView *view = (GioView *)window.contentView; + if ([window firstResponder] == view) { + gio_onFocus(view.handle, 0); + } } @end @@ -205,6 +209,14 @@ - (void)applicationDidHide:(NSNotification *)notification { - (void)dealloc { gio_onDestroy(self.handle); } +- (BOOL) becomeFirstResponder { + gio_onFocus(self.handle, 1); + return [super becomeFirstResponder]; + } +- (BOOL) resignFirstResponder { + gio_onFocus(self.handle, 0); + return [super resignFirstResponder]; +} @end // Delegates are weakly referenced from their peers. Nothing diff --git a/vendor/gioui.org/app/os_wayland.go b/vendor/gioui.org/app/os_wayland.go index 550a4917..0689655d 100644 --- a/vendor/gioui.org/app/os_wayland.go +++ b/vendor/gioui.org/app/os_wayland.go @@ -216,6 +216,8 @@ type window struct { wakeups chan struct{} + closing bool + // invMu avoids the race between the destruction of disp and // Invalidate waking it up. invMu sync.Mutex @@ -556,7 +558,7 @@ func gio_onXdgSurfaceConfigure(data unsafe.Pointer, wmSurf *C.struct_xdg_surface //export gio_onToplevelClose func gio_onToplevelClose(data unsafe.Pointer, topLvl *C.struct_xdg_toplevel) { w := callbackLoad(data).(*window) - w.close(nil) + w.closing = true } //export gio_onToplevelConfigure @@ -1139,7 +1141,7 @@ func (w *window) Perform(actions system.Action) { walkActions(actions, func(action system.Action) { switch action { case system.ActionClose: - w.close(nil) + w.closing = true } }) } @@ -1366,6 +1368,11 @@ func gio_onFrameDone(data unsafe.Pointer, callback *C.struct_wl_callback, t C.ui func (w *window) close(err error) { w.ProcessEvent(WaylandViewEvent{}) w.ProcessEvent(DestroyEvent{Err: err}) + w.destroy() + w.invMu.Lock() + w.disp.destroy() + w.disp = nil + w.invMu.Unlock() } func (w *window) dispatch() { @@ -1374,7 +1381,7 @@ func (w *window) dispatch() { w.w.Invalidate() return } - if err := w.disp.dispatch(); err != nil { + if err := w.disp.dispatch(); err != nil || w.closing { w.close(err) return } @@ -1399,13 +1406,6 @@ func (w *window) Event() event.Event { w.dispatch() continue } - if _, destroy := evt.(DestroyEvent); destroy { - w.destroy() - w.invMu.Lock() - w.disp.destroy() - w.disp = nil - w.invMu.Unlock() - } return evt } } @@ -1515,6 +1515,10 @@ func (d *wlDisplay) wakeup() { } func (w *window) destroy() { + if w.lastFrameCallback != nil { + C.wl_callback_destroy(w.lastFrameCallback) + w.lastFrameCallback = nil + } if w.cursor.surf != nil { C.wl_surface_destroy(w.cursor.surf) } diff --git a/vendor/gioui.org/app/os_x11.go b/vendor/gioui.org/app/os_x11.go index f5ea42a6..3865f25d 100644 --- a/vendor/gioui.org/app/os_x11.go +++ b/vendor/gioui.org/app/os_x11.go @@ -389,6 +389,7 @@ func (w *x11Window) ProcessEvent(e event.Event) { func (w *x11Window) shutdown(err error) { w.ProcessEvent(X11ViewEvent{}) w.ProcessEvent(DestroyEvent{Err: err}) + w.destroy() } func (w *x11Window) Event() event.Event { @@ -398,9 +399,6 @@ func (w *x11Window) Event() event.Event { w.dispatch() continue } - if _, destroy := evt.(DestroyEvent); destroy { - w.destroy() - } return evt } } @@ -464,7 +462,12 @@ func (w *x11Window) dispatch() { // Check for pending draw events before checking animation or blocking. // This fixes an issue on Xephyr where on startup XPending() > 0 but // poll will still block. This also prevents no-op calls to poll. - if syn = w.handler.handleEvents(); !syn { + syn = w.handler.handleEvents() + if w.x == nil { + // handleEvents received a close request and destroyed the window. + return + } + if !syn { anim = w.animating if !anim { // Clear poll events. @@ -476,6 +479,9 @@ func (w *x11Window) dispatch() { switch { case *xEvents&syscall.POLLIN != 0: syn = w.handler.handleEvents() + if w.x == nil { + return + } case *xEvents&(syscall.POLLERR|syscall.POLLHUP) != 0: } } diff --git a/vendor/gioui.org/app/window.go b/vendor/gioui.org/app/window.go index 7e88fad8..70f6a359 100644 --- a/vendor/gioui.org/app/window.go +++ b/vendor/gioui.org/app/window.go @@ -9,7 +9,6 @@ import ( "image/color" "reflect" "runtime" - "sync" "time" "unicode/utf8" @@ -36,14 +35,14 @@ type Option func(unit.Metric, *Config) // Window represents an operating system window. // -// The zero-value Window is useful, and calling any method on -// it creates and shows a new GUI window. On iOS or Android, -// the first Window represents the the window previously -// created by the platform. +// The zero-value Window is useful; the GUI window is created and shown the first +// time the [Event] method is called. On iOS or Android, the first Window represents +// the window previously created by the platform. // -// More than one Window is not supported on iOS, Android, -// WebAssembly. +// More than one Window is not supported on iOS, Android, WebAssembly. type Window struct { + initialOpts []Option + ctx context gpu gpu.GPU // timer tracks the delayed invalidate goroutine. @@ -91,11 +90,10 @@ type Window struct { driver driver // basic is the driver interface that is needed even after the window is gone. basic basicDriver - once sync.Once // coalesced tracks the most recent events waiting to be delivered // to the client. coalesced eventSummary - // frame tracks the most recently frame event. + // frame tracks the most recent frame event. lastFrame struct { sync bool size image.Point @@ -273,8 +271,9 @@ func (w *Window) updateState() { // // Invalidate is safe for concurrent use. func (w *Window) Invalidate() { - w.init() - w.basic.Invalidate() + if w.basic != nil { + w.basic.Invalidate() + } } // Option applies the options to the window. The options are hints; the platform is @@ -283,7 +282,10 @@ func (w *Window) Option(opts ...Option) { if len(opts) == 0 { return } - w.init(opts...) + if w.basic == nil { + w.initialOpts = append(w.initialOpts, opts...) + return + } w.Run(func() { cnf := Config{Decorated: w.decorations.enabled} for _, opt := range opts { @@ -302,13 +304,14 @@ func (w *Window) Option(opts ...Option) { } // Run f in the same thread as the native window event loop, and wait for f to -// return or the window to close. +// return or the window to close. If the window has not yet been created, +// Run calls f directly. // // Note that most programs should not call Run; configuring a Window with // [CustomRenderer] is a notable exception. func (w *Window) Run(f func()) { - w.init() if w.driver == nil { + f() return } done := make(chan struct{}) @@ -680,48 +683,50 @@ func (w *Window) processEvent(e event.Event) bool { } // Event blocks until an event is received from the window, such as -// [FrameEvent], or until [Invalidate] is called. +// [FrameEvent], or until [Invalidate] is called. The window is created +// and shown the first time Event is called. func (w *Window) Event() event.Event { - w.init() + if w.basic == nil { + w.init() + } return w.basic.Event() } -func (w *Window) init(initial ...Option) { - w.once.Do(func() { - debug.Parse() - // Measure decoration height. - deco := new(widget.Decorations) - theme := material.NewTheme() - theme.Shaper = text.NewShaper(text.NoSystemFonts(), text.WithCollection(gofont.Regular())) - decoStyle := material.Decorations(theme, deco, 0, "") - gtx := layout.Context{ - Ops: new(op.Ops), - // Measure in Dp. - Metric: unit.Metric{}, - } - // Allow plenty of space. - gtx.Constraints.Max.Y = 200 - dims := decoStyle.Layout(gtx) - decoHeight := unit.Dp(dims.Size.Y) - defaultOptions := []Option{ - Size(800, 600), - Title("Gio"), - Decorated(true), - decoHeightOpt(decoHeight), - } - options := append(defaultOptions, initial...) - var cnf Config - cnf.apply(unit.Metric{}, options) - - w.nocontext = cnf.CustomRenderer - w.decorations.Theme = theme - w.decorations.Decorations = deco - w.decorations.enabled = cnf.Decorated - w.decorations.height = decoHeight - w.imeState.compose = key.Range{Start: -1, End: -1} - w.semantic.ids = make(map[input.SemanticID]input.SemanticNode) - newWindow(&callbacks{w}, options) - }) +func (w *Window) init() { + debug.Parse() + // Measure decoration height. + deco := new(widget.Decorations) + theme := material.NewTheme() + theme.Shaper = text.NewShaper(text.NoSystemFonts(), text.WithCollection(gofont.Regular())) + decoStyle := material.Decorations(theme, deco, 0, "") + gtx := layout.Context{ + Ops: new(op.Ops), + // Measure in Dp. + Metric: unit.Metric{}, + } + // Allow plenty of space. + gtx.Constraints.Max.Y = 200 + dims := decoStyle.Layout(gtx) + decoHeight := unit.Dp(dims.Size.Y) + defaultOptions := []Option{ + Size(800, 600), + Title("Gio"), + Decorated(true), + decoHeightOpt(decoHeight), + } + options := append(defaultOptions, w.initialOpts...) + w.initialOpts = nil + var cnf Config + cnf.apply(unit.Metric{}, options) + + w.nocontext = cnf.CustomRenderer + w.decorations.Theme = theme + w.decorations.Decorations = deco + w.decorations.enabled = cnf.Decorated + w.decorations.height = decoHeight + w.imeState.compose = key.Range{Start: -1, End: -1} + w.semantic.ids = make(map[input.SemanticID]input.SemanticNode) + newWindow(&callbacks{w}, options) } func (w *Window) updateCursor() { @@ -769,8 +774,12 @@ func (w *Window) decorate(e FrameEvent, o *op.Ops) image.Point { } // Update the window based on the actions on the decorations. opts, acts := splitActions(deco.Update(gtx)) - w.driver.Configure(opts) - w.driver.Perform(acts) + if len(opts) > 0 { + w.driver.Configure(opts) + } + if acts != 0 { + w.driver.Perform(acts) + } style.Layout(gtx) // Offset to place the frame content below the decorations. decoHeight := gtx.Dp(w.decorations.Config.decoHeight) diff --git a/vendor/gioui.org/gesture/gesture.go b/vendor/gioui.org/gesture/gesture.go index 70e87707..0800a53c 100644 --- a/vendor/gioui.org/gesture/gesture.go +++ b/vendor/gioui.org/gesture/gesture.go @@ -271,12 +271,13 @@ func (s *Scroll) Stop() { } // Update state and report the scroll distance along axis. -func (s *Scroll) Update(cfg unit.Metric, q input.Source, t time.Time, axis Axis, bounds image.Rectangle) int { +func (s *Scroll) Update(cfg unit.Metric, q input.Source, t time.Time, axis Axis, scrollx, scrolly pointer.ScrollRange) int { total := 0 f := pointer.Filter{ - Target: s, - Kinds: pointer.Press | pointer.Drag | pointer.Release | pointer.Scroll | pointer.Cancel, - ScrollBounds: bounds, + Target: s, + Kinds: pointer.Press | pointer.Drag | pointer.Release | pointer.Scroll | pointer.Cancel, + ScrollX: scrollx, + ScrollY: scrolly, } for { evt, ok := q.Event(f) diff --git a/vendor/gioui.org/gpu/gpu.go b/vendor/gioui.org/gpu/gpu.go index e481af7f..ea5a6b02 100644 --- a/vendor/gioui.org/gpu/gpu.go +++ b/vendor/gioui.org/gpu/gpu.go @@ -261,7 +261,7 @@ type texture struct { type blitter struct { ctx driver.Device viewport image.Point - pipelines [3]*pipeline + pipelines [2][3]*pipeline colUniforms *blitColUniforms texUniforms *blitTexUniforms linearGradientUniforms *blitLinearGradientUniforms @@ -560,12 +560,24 @@ func newBlitter(ctx driver.Device) *blitter { func (b *blitter) release() { b.quadVerts.Release() for _, p := range b.pipelines { - p.Release() + for _, p := range p { + p.Release() + } } } -func createColorPrograms(b driver.Device, vsSrc shader.Sources, fsSrc [3]shader.Sources, uniforms [3]interface{}) ([3]*pipeline, error) { - var pipelines [3]*pipeline +func createColorPrograms(b driver.Device, vsSrc shader.Sources, fsSrc [3]shader.Sources, uniforms [3]interface{}) (pipelines [2][3]*pipeline, err error) { + defer func() { + if err != nil { + for _, p := range pipelines { + for _, p := range p { + if p != nil { + p.Release() + } + } + } + } + }() blend := driver.BlendDesc{ Enable: true, SrcFactor: driver.BlendFactorOne, @@ -583,86 +595,76 @@ func createColorPrograms(b driver.Device, vsSrc shader.Sources, fsSrc [3]shader. return pipelines, err } defer vsh.Release() - { - fsh, err := b.NewFragmentShader(fsSrc[materialTexture]) - if err != nil { - return pipelines, err - } - defer fsh.Release() - pipe, err := b.NewPipeline(driver.PipelineDesc{ - VertexShader: vsh, - FragmentShader: fsh, - BlendDesc: blend, - VertexLayout: layout, - PixelFormat: driver.TextureFormatOutput, - Topology: driver.TopologyTriangleStrip, - }) - if err != nil { - return pipelines, err - } - var vertBuffer *uniformBuffer - if u := uniforms[materialTexture]; u != nil { - vertBuffer = newUniformBuffer(b, u) - } - pipelines[materialTexture] = &pipeline{pipe, vertBuffer} - } - { - var vertBuffer *uniformBuffer - fsh, err := b.NewFragmentShader(fsSrc[materialColor]) - if err != nil { - pipelines[materialTexture].Release() - return pipelines, err - } - defer fsh.Release() - pipe, err := b.NewPipeline(driver.PipelineDesc{ - VertexShader: vsh, - FragmentShader: fsh, - BlendDesc: blend, - VertexLayout: layout, - PixelFormat: driver.TextureFormatOutput, - Topology: driver.TopologyTriangleStrip, - }) - if err != nil { - pipelines[materialTexture].Release() - return pipelines, err - } - if u := uniforms[materialColor]; u != nil { - vertBuffer = newUniformBuffer(b, u) - } - pipelines[materialColor] = &pipeline{pipe, vertBuffer} - } - { - var vertBuffer *uniformBuffer - fsh, err := b.NewFragmentShader(fsSrc[materialLinearGradient]) - if err != nil { - pipelines[materialTexture].Release() - pipelines[materialColor].Release() - return pipelines, err - } - defer fsh.Release() - pipe, err := b.NewPipeline(driver.PipelineDesc{ - VertexShader: vsh, - FragmentShader: fsh, - BlendDesc: blend, - VertexLayout: layout, - PixelFormat: driver.TextureFormatOutput, - Topology: driver.TopologyTriangleStrip, - }) - if err != nil { - pipelines[materialTexture].Release() - pipelines[materialColor].Release() - return pipelines, err + for i, format := range []driver.TextureFormat{driver.TextureFormatOutput, driver.TextureFormatSRGBA} { + { + fsh, err := b.NewFragmentShader(fsSrc[materialTexture]) + if err != nil { + return pipelines, err + } + defer fsh.Release() + pipe, err := b.NewPipeline(driver.PipelineDesc{ + VertexShader: vsh, + FragmentShader: fsh, + BlendDesc: blend, + VertexLayout: layout, + PixelFormat: format, + Topology: driver.TopologyTriangleStrip, + }) + if err != nil { + return pipelines, err + } + var vertBuffer *uniformBuffer + if u := uniforms[materialTexture]; u != nil { + vertBuffer = newUniformBuffer(b, u) + } + pipelines[i][materialTexture] = &pipeline{pipe, vertBuffer} } - if u := uniforms[materialLinearGradient]; u != nil { - vertBuffer = newUniformBuffer(b, u) + { + var vertBuffer *uniformBuffer + fsh, err := b.NewFragmentShader(fsSrc[materialColor]) + if err != nil { + return pipelines, err + } + defer fsh.Release() + pipe, err := b.NewPipeline(driver.PipelineDesc{ + VertexShader: vsh, + FragmentShader: fsh, + BlendDesc: blend, + VertexLayout: layout, + PixelFormat: format, + Topology: driver.TopologyTriangleStrip, + }) + if err != nil { + return pipelines, err + } + if u := uniforms[materialColor]; u != nil { + vertBuffer = newUniformBuffer(b, u) + } + pipelines[i][materialColor] = &pipeline{pipe, vertBuffer} } - pipelines[materialLinearGradient] = &pipeline{pipe, vertBuffer} - } - if err != nil { - for _, p := range pipelines { - p.Release() + { + var vertBuffer *uniformBuffer + fsh, err := b.NewFragmentShader(fsSrc[materialLinearGradient]) + if err != nil { + return pipelines, err + } + defer fsh.Release() + pipe, err := b.NewPipeline(driver.PipelineDesc{ + VertexShader: vsh, + FragmentShader: fsh, + BlendDesc: blend, + VertexLayout: layout, + PixelFormat: format, + Topology: driver.TopologyTriangleStrip, + }) + if err != nil { + return pipelines, err + } + if u := uniforms[materialLinearGradient]; u != nil { + vertBuffer = newUniformBuffer(b, u) + } + pipelines[i][materialLinearGradient] = &pipeline{pipe, vertBuffer} } - return pipelines, err } return pipelines, nil } @@ -865,7 +867,7 @@ func (r *renderer) drawLayers(layers []opacityLayer, ops []imageOp) { Min: l.place.Pos, Max: l.place.Pos.Add(l.clip.Size()), } - r.ctx.Viewport(v.Min.X, v.Min.Y, v.Max.X, v.Max.Y) + r.ctx.Viewport(v.Min.X, v.Min.Y, v.Dx(), v.Dy()) f := r.layerFBOs.fbos[fbo] r.drawOps(true, l.clip.Min.Mul(-1), l.clip.Size(), ops[l.opStart:l.opEnd]) sr := f32.FRect(v) @@ -930,7 +932,7 @@ func (d *drawOps) newPathOp() *pathOp { return &d.pathOpCache[len(d.pathOpCache)-1] } -func (d *drawOps) addClipPath(state *drawState, aux []byte, auxKey opKey, bounds f32.Rectangle, off f32.Point, push bool) { +func (d *drawOps) addClipPath(state *drawState, aux []byte, auxKey opKey, bounds f32.Rectangle, off f32.Point) { npath := d.newPathOp() *npath = pathOp{ parent: state.cpath, @@ -1055,7 +1057,7 @@ loop: quads.aux, bounds, _ = d.boundsForTransformedRect(bounds, trans) quads.key = opKey{Key: encOp.Key} } - d.addClipPath(&state, quads.aux, quads.key, bounds, off, true) + d.addClipPath(&state, quads.aux, quads.key, bounds, off) quads = quadsOp{} case ops.TypePopClip: state.cpath = state.cpath.parent @@ -1100,7 +1102,7 @@ loop: // this transformed rectangle. k := opKey{Key: encOp.Key} k.SetTransform(t) // TODO: This call has no effect. - d.addClipPath(&state, clipData, k, bnd, off, false) + d.addClipPath(&state, clipData, k, bnd, off) } bounds := cl.Round() @@ -1230,7 +1232,7 @@ func (r *renderer) prepareDrawOps(ops []imageOp) { } } -func (r *renderer) drawOps(isFBO bool, opOff image.Point, viewport image.Point, ops []imageOp) { +func (r *renderer) drawOps(isFBO bool, opOff, viewport image.Point, ops []imageOp) { var coverTex driver.Texture for i := 0; i < len(ops); i++ { img := ops[i] @@ -1244,9 +1246,13 @@ func (r *renderer) drawOps(isFBO bool, opOff image.Point, viewport image.Point, scale, off := clipSpaceTransform(drc, viewport) var fbo FBO + fboIdx := 0 + if isFBO { + fboIdx = 1 + } switch img.clipType { case clipTypeNone: - p := r.blitter.pipelines[m.material] + p := r.blitter.pipelines[fboIdx][m.material] r.ctx.BindPipeline(p.pipeline) r.ctx.BindVertexBuffer(r.blitter.quadVerts, 0) r.blitter.blit(m.material, isFBO, m.color, m.color1, m.color2, scale, off, m.opacity, m.uvTrans) @@ -1265,7 +1271,7 @@ func (r *renderer) drawOps(isFBO bool, opOff image.Point, viewport image.Point, Max: img.place.Pos.Add(drc.Size()), } coverScale, coverOff := texSpaceTransform(f32.FRect(uv), fbo.size) - p := r.pather.coverer.pipelines[m.material] + p := r.pather.coverer.pipelines[fboIdx][m.material] r.ctx.BindPipeline(p.pipeline) r.ctx.BindVertexBuffer(r.blitter.quadVerts, 0) r.pather.cover(m.material, isFBO, m.color, m.color1, m.color2, scale, off, m.uvTrans, coverScale, coverOff) @@ -1273,7 +1279,11 @@ func (r *renderer) drawOps(isFBO bool, opOff image.Point, viewport image.Point, } func (b *blitter) blit(mat materialType, fbo bool, col f32color.RGBA, col1, col2 f32color.RGBA, scale, off f32.Point, opacity float32, uvTrans f32.Affine2D) { - p := b.pipelines[mat] + fboIdx := 0 + if fbo { + fboIdx = 1 + } + p := b.pipelines[fboIdx][mat] b.ctx.BindPipeline(p.pipeline) var uniforms *blitUniforms switch mat { diff --git a/vendor/gioui.org/gpu/path.go b/vendor/gioui.org/gpu/path.go index e4622677..eb8489b5 100644 --- a/vendor/gioui.org/gpu/path.go +++ b/vendor/gioui.org/gpu/path.go @@ -30,7 +30,7 @@ type pather struct { type coverer struct { ctx driver.Device - pipelines [3]*pipeline + pipelines [2][3]*pipeline texUniforms *coverTexUniforms colUniforms *coverColUniforms linearGradientUniforms *coverLinearGradientUniforms @@ -309,7 +309,9 @@ func (p *pather) release() { func (c *coverer) release() { for _, p := range c.pipelines { - p.Release() + for _, p := range p { + p.Release() + } } } @@ -405,7 +407,11 @@ func (c *coverer) cover(mat materialType, isFBO bool, col f32color.RGBA, col1, c } uniforms.transform = [4]float32{scale.X, scale.Y, off.X, off.Y} uniforms.uvCoverTransform = [4]float32{coverScale.X, coverScale.Y, coverOff.X, coverOff.Y} - c.pipelines[mat].UploadUniforms(c.ctx) + fboIdx := 0 + if isFBO { + fboIdx = 1 + } + c.pipelines[fboIdx][mat].UploadUniforms(c.ctx) c.ctx.DrawArrays(0, 4) } diff --git a/vendor/gioui.org/internal/egl/egl.go b/vendor/gioui.org/internal/egl/egl.go index 90dd9009..ab2eab76 100644 --- a/vendor/gioui.org/internal/egl/egl.go +++ b/vendor/gioui.org/internal/egl/egl.go @@ -15,10 +15,9 @@ import ( ) type Context struct { - disp _EGLDisplay - eglCtx *eglContext - eglSurf _EGLSurface - width, height int + disp _EGLDisplay + eglCtx *eglContext + eglSurf _EGLSurface } type eglContext struct { @@ -121,11 +120,9 @@ func (c *Context) VisualID() int { return c.eglCtx.visualID } -func (c *Context) CreateSurface(win NativeWindowType, width, height int) error { +func (c *Context) CreateSurface(win NativeWindowType) error { eglSurf, err := createSurface(c.disp, c.eglCtx, win) c.eglSurf = eglSurf - c.width = width - c.height = height return err } diff --git a/vendor/gioui.org/internal/gl/gl_windows.go b/vendor/gioui.org/internal/gl/gl_windows.go index edf688df..a30457fd 100644 --- a/vendor/gioui.org/internal/gl/gl_windows.go +++ b/vendor/gioui.org/internal/gl/gl_windows.go @@ -361,6 +361,9 @@ func (c *Functions) GetProgrami(p Program, pname Enum) int { } func (c *Functions) GetProgramInfoLog(p Program) string { n := c.GetProgrami(p, INFO_LOG_LENGTH) + if n == 0 { + return "" + } buf := make([]byte, n) syscall.Syscall6(_glGetProgramInfoLog.Addr(), 4, uintptr(p.V), uintptr(len(buf)), 0, uintptr(unsafe.Pointer(&buf[0])), 0, 0) return string(buf) diff --git a/vendor/gioui.org/internal/stroke/stroke.go b/vendor/gioui.org/internal/stroke/stroke.go index 43752898..1a647de5 100644 --- a/vendor/gioui.org/internal/stroke/stroke.go +++ b/vendor/gioui.org/internal/stroke/stroke.go @@ -327,6 +327,9 @@ func strokePathNorm(p0, p1, p2 f32.Point, t, d float32) f32.Point { func rot90CW(p f32.Point) f32.Point { return f32.Pt(+p.Y, -p.X) } func normPt(p f32.Point, l float32) f32.Point { + if (p.X == 0 && p.Y == l) || (p.Y == 0 && p.X == l) { + return f32.Point{X: p.X, Y: p.Y} + } d := math.Hypot(float64(p.X), float64(p.Y)) l64 := float64(l) if math.Abs(d-l64) < 1e-10 { diff --git a/vendor/gioui.org/io/input/pointer.go b/vendor/gioui.org/io/input/pointer.go index cc90f3f8..e084e780 100644 --- a/vendor/gioui.org/io/input/pointer.go +++ b/vendor/gioui.org/io/input/pointer.go @@ -72,7 +72,7 @@ type pointerHandler struct { type pointerFilter struct { kinds pointer.Kind // min and max horizontal/vertical scroll - scrollRange image.Rectangle + scrollX, scrollY pointer.ScrollRange sourceMimes []string targetMimes []string @@ -297,7 +297,8 @@ func (p *pointerFilter) Add(f event.Filter) { p.targetMimes = append(p.targetMimes, f.Type) case pointer.Filter: p.kinds = p.kinds | f.Kinds - p.scrollRange = p.scrollRange.Union(f.ScrollBounds) + p.scrollX = p.scrollX.Union(f.ScrollX) + p.scrollY = p.scrollY.Union(f.ScrollY) } } @@ -325,7 +326,8 @@ func (p *pointerFilter) Matches(e event.Event) bool { func (p *pointerFilter) Merge(p2 pointerFilter) { p.kinds = p.kinds | p2.kinds - p.scrollRange = p.scrollRange.Union(p2.scrollRange) + p.scrollX = p.scrollX.Union(p2.scrollX) + p.scrollY = p.scrollY.Union(p2.scrollY) p.sourceMimes = append(p.sourceMimes, p2.sourceMimes...) p.targetMimes = append(p.targetMimes, p2.targetMimes...) } @@ -333,8 +335,8 @@ func (p *pointerFilter) Merge(p2 pointerFilter) { // clampScroll splits a scroll distance in the remaining scroll and the // scroll accepted by the filter. func (p *pointerFilter) clampScroll(scroll f32.Point) (left, scrolled f32.Point) { - left.X, scrolled.X = clampSplit(scroll.X, p.scrollRange.Min.X, p.scrollRange.Max.X) - left.Y, scrolled.Y = clampSplit(scroll.Y, p.scrollRange.Min.Y, p.scrollRange.Max.Y) + left.X, scrolled.X = clampSplit(scroll.X, p.scrollX.Min, p.scrollX.Max) + left.Y, scrolled.Y = clampSplit(scroll.Y, p.scrollY.Min, p.scrollY.Max) return } diff --git a/vendor/gioui.org/io/input/router.go b/vendor/gioui.org/io/input/router.go index 99962a1a..9e07e9a6 100644 --- a/vendor/gioui.org/io/input/router.go +++ b/vendor/gioui.org/io/input/router.go @@ -35,10 +35,9 @@ type Router struct { queue keyQueue // The following fields have the same purpose as the fields in // type handler, but for key.Events. - filter keyFilter - nextFilter keyFilter - processedFilter keyFilter - scratchFilter keyFilter + filter keyFilter + nextFilter keyFilter + scratchFilter keyFilter } cqueue clipboardQueue // states is the list of pending state changes resulting from @@ -304,7 +303,6 @@ func (q *Router) Event(filters ...event.Filter) (event.Event, bool) { h := q.stateFor(tf.tag) h.processedFilter.Merge(tf.filter) } - q.key.processedFilter = append(q.key.processedFilter, q.key.scratchFilter...) return nil, false } diff --git a/vendor/gioui.org/io/pointer/doc.go b/vendor/gioui.org/io/pointer/doc.go index c70ef8ae..ad2993d2 100644 --- a/vendor/gioui.org/io/pointer/doc.go +++ b/vendor/gioui.org/io/pointer/doc.go @@ -37,11 +37,11 @@ For example: var h1, h2 *Handler area := clip.Rect(...).Push(ops) - event.Op{Tag: h1}.Add(Ops) + event.Op(Ops, h1) area.Pop() area := clip.Rect(...).Push(ops) - event.Op{Tag: h2}.Add(ops) + event.Op(Ops, h2) area.Pop() implies a tree of two inner nodes, each with one pointer handler attached. diff --git a/vendor/gioui.org/io/pointer/pointer.go b/vendor/gioui.org/io/pointer/pointer.go index 8b9b42fb..45625991 100644 --- a/vendor/gioui.org/io/pointer/pointer.go +++ b/vendor/gioui.org/io/pointer/pointer.go @@ -3,7 +3,6 @@ package pointer import ( - "image" "strings" "time" @@ -61,12 +60,19 @@ type Filter struct { Target event.Tag // Kinds is a bitwise-or of event types to match. Kinds Kind - // ScrollBounds describe the maximum scrollable distances in both - // axes. Specifically, any Event e delivered to Tag will satisfy + // ScrollX and ScrollY constrain the range of scrolling events delivered + // to Target. Specifically, any Event e delivered to Tag will satisfy // - // ScrollBounds.Min.X <= e.Scroll.X <= ScrollBounds.Max.X (horizontal axis) - // ScrollBounds.Min.Y <= e.Scroll.Y <= ScrollBounds.Max.Y (vertical axis) - ScrollBounds image.Rectangle + // ScrollX.Min <= e.Scroll.X <= ScrollX.Max (horizontal axis) + // ScrollY.Min <= e.Scroll.Y <= ScrollY.Max (vertical axis) + ScrollX ScrollRange + ScrollY ScrollRange +} + +// ScrollRange describes the range of scrolling distances in an +// axis. +type ScrollRange struct { + Min, Max int } // GrabCmd requests a pointer grab on the pointer identified by ID. @@ -219,6 +225,13 @@ const ( ButtonTertiary ) +func (s ScrollRange) Union(s2 ScrollRange) ScrollRange { + return ScrollRange{ + Min: min(s.Min, s2.Min), + Max: max(s.Max, s2.Max), + } +} + // Push the current pass mode to the pass stack and set the pass mode. func (p PassOp) Push(o *op.Ops) PassStack { id, mid := ops.PushOp(&o.Internal, ops.PassStack) diff --git a/vendor/gioui.org/layout/list.go b/vendor/gioui.org/layout/list.go index c34fc901..3cd7cea4 100644 --- a/vendor/gioui.org/layout/list.go +++ b/vendor/gioui.org/layout/list.go @@ -7,6 +7,7 @@ import ( "math" "gioui.org/gesture" + "gioui.org/io/pointer" "gioui.org/op" "gioui.org/op/clip" ) @@ -158,11 +159,12 @@ func (l *List) update(gtx Context) { max = 0 } } - scrollRange := image.Rectangle{ - Min: l.Axis.Convert(image.Pt(min, 0)), - Max: l.Axis.Convert(image.Pt(max, 0)), + xrange := pointer.ScrollRange{Min: min, Max: max} + yrange := pointer.ScrollRange{} + if l.Axis == Vertical { + xrange, yrange = yrange, xrange } - d := l.scroll.Update(gtx.Metric, gtx.Source, gtx.Now, gesture.Axis(l.Axis), scrollRange) + d := l.scroll.Update(gtx.Metric, gtx.Source, gtx.Now, gesture.Axis(l.Axis), xrange, yrange) l.scrollDelta = d l.Position.Offset += d } diff --git a/vendor/gioui.org/op/clip/clip.go b/vendor/gioui.org/op/clip/clip.go index 98024ab9..d353d936 100644 --- a/vendor/gioui.org/op/clip/clip.go +++ b/vendor/gioui.org/op/clip/clip.go @@ -138,6 +138,9 @@ type Path struct { func (p *Path) Pos() f32.Point { return p.pen } // Begin the path, storing the path data and final Op into ops. +// +// Caller must also call End to finish the drawing. +// Forgetting to call it will result in a "panic: cannot mix multi ops with single ones". func (p *Path) Begin(o *op.Ops) { *p = Path{ ops: &o.Internal, diff --git a/vendor/gioui.org/widget/editor.go b/vendor/gioui.org/widget/editor.go index c43e794b..38783f03 100644 --- a/vendor/gioui.org/widget/editor.go +++ b/vendor/gioui.org/widget/editor.go @@ -228,19 +228,19 @@ func (e *Editor) processPointer(gtx layout.Context) (EditorEvent, bool) { axis = gesture.Vertical smin, smax = sbounds.Min.Y, sbounds.Max.Y } - var scrollRange image.Rectangle + var scrollX, scrollY pointer.ScrollRange textDims := e.text.FullDimensions() visibleDims := e.text.Dimensions() if e.SingleLine { scrollOffX := e.text.ScrollOff().X - scrollRange.Min.X = min(-scrollOffX, 0) - scrollRange.Max.X = max(0, textDims.Size.X-(scrollOffX+visibleDims.Size.X)) + scrollX.Min = min(-scrollOffX, 0) + scrollX.Max = max(0, textDims.Size.X-(scrollOffX+visibleDims.Size.X)) } else { scrollOffY := e.text.ScrollOff().Y - scrollRange.Min.Y = -scrollOffY - scrollRange.Max.Y = max(0, textDims.Size.Y-(scrollOffY+visibleDims.Size.Y)) + scrollY.Min = -scrollOffY + scrollY.Max = max(0, textDims.Size.Y-(scrollOffY+visibleDims.Size.Y)) } - sdist := e.scroller.Update(gtx.Metric, gtx.Source, gtx.Now, axis, scrollRange) + sdist := e.scroller.Update(gtx.Metric, gtx.Source, gtx.Now, axis, scrollX, scrollY) var soff int if e.SingleLine { e.text.ScrollRel(sdist, 0) @@ -289,6 +289,9 @@ func (e *Editor) processPointerEvent(gtx layout.Context, ev event.Event) (Editor Y: int(math.Round(float64(evt.Position.Y))), }) gtx.Execute(key.FocusCmd{Tag: e}) + if !e.ReadOnly { + gtx.Execute(key.SoftKeyboardCmd{Show: true}) + } if e.scroller.State() != gesture.StateFlinging { e.scrollCaret = true } @@ -312,8 +315,8 @@ func (e *Editor) processPointerEvent(gtx layout.Context, ev event.Event) (Editor e.text.MoveWord(1, selectionExtend) e.dragging = false case evt.NumClicks >= 3: - e.text.MoveStart(selectionClear) - e.text.MoveEnd(selectionExtend) + e.text.MoveLineStart(selectionClear) + e.text.MoveLineEnd(selectionExtend) e.dragging = false } } @@ -374,8 +377,8 @@ func (e *Editor) processKey(gtx layout.Context) (EditorEvent, bool) { key.Filter{Focus: e, Name: key.NameDeleteBackward, Optional: key.ModShortcutAlt | key.ModShift}, key.Filter{Focus: e, Name: key.NameDeleteForward, Optional: key.ModShortcutAlt | key.ModShift}, - key.Filter{Focus: e, Name: key.NameHome, Optional: key.ModShift}, - key.Filter{Focus: e, Name: key.NameEnd, Optional: key.ModShift}, + key.Filter{Focus: e, Name: key.NameHome, Optional: key.ModShortcut | key.ModShift}, + key.Filter{Focus: e, Name: key.NameEnd, Optional: key.ModShortcut | key.ModShift}, key.Filter{Focus: e, Name: key.NamePageDown, Optional: key.ModShift}, key.Filter{Focus: e, Name: key.NamePageUp, Optional: key.ModShift}, condFilter(!atBeginning, key.Filter{Focus: e, Name: key.NameLeftArrow, Optional: key.ModShortcutAlt | key.ModShift}), @@ -395,7 +398,7 @@ func (e *Editor) processKey(gtx layout.Context) (EditorEvent, bool) { case key.FocusEvent: // Reset IME state. e.ime.imeState = imeState{} - if ke.Focus { + if ke.Focus && !e.ReadOnly { gtx.Execute(key.SoftKeyboardCmd{Show: true}) } case key.Event: @@ -521,6 +524,10 @@ func (e *Editor) command(gtx layout.Context, k key.Event) (EditorEvent, bool) { } } } + case key.NameHome: + e.text.MoveTextStart(selAct) + case key.NameEnd: + e.text.MoveTextEnd(selAct) } return nil, false } @@ -582,9 +589,9 @@ func (e *Editor) command(gtx layout.Context, k key.Event) (EditorEvent, bool) { case key.NamePageDown: e.text.MovePages(+1, selAct) case key.NameHome: - e.text.MoveStart(selAct) + e.text.MoveLineStart(selAct) case key.NameEnd: - e.text.MoveEnd(selAct) + e.text.MoveLineEnd(selAct) } return nil, false } diff --git a/vendor/gioui.org/widget/material/progressbar.go b/vendor/gioui.org/widget/material/progressbar.go index c842171d..00d4c9f6 100644 --- a/vendor/gioui.org/widget/material/progressbar.go +++ b/vendor/gioui.org/widget/material/progressbar.go @@ -54,6 +54,9 @@ func (p ProgressBarStyle) Layout(gtx layout.Context) layout.Dimensions { if !gtx.Enabled() { fillColor = f32color.Disabled(fillColor) } + if fillWidth < int(p.Radius*2) { + fillWidth = int(p.Radius * 2) + } return shader(fillWidth, fillColor) }), ) diff --git a/vendor/gioui.org/widget/selectable.go b/vendor/gioui.org/widget/selectable.go index ed1132e9..63cb2ff8 100644 --- a/vendor/gioui.org/widget/selectable.go +++ b/vendor/gioui.org/widget/selectable.go @@ -247,8 +247,8 @@ func (e *Selectable) processPointer(gtx layout.Context) { e.text.MoveWord(1, selectionExtend) e.dragging = false case evt.NumClicks >= 3: - e.text.MoveStart(selectionClear) - e.text.MoveEnd(selectionExtend) + e.text.MoveLineStart(selectionClear) + e.text.MoveLineEnd(selectionExtend) e.dragging = false } } @@ -378,9 +378,9 @@ func (e *Selectable) command(gtx layout.Context, k key.Event) { case key.NamePageDown: e.text.MovePages(+1, selAct) case key.NameHome: - e.text.MoveStart(selAct) + e.text.MoveLineStart(selAct) case key.NameEnd: - e.text.MoveEnd(selAct) + e.text.MoveLineEnd(selAct) } } diff --git a/vendor/gioui.org/widget/text.go b/vendor/gioui.org/widget/text.go index 52cfb1e2..88e9d17f 100644 --- a/vendor/gioui.org/widget/text.go +++ b/vendor/gioui.org/widget/text.go @@ -639,9 +639,28 @@ func (e *textView) MoveCaret(startDelta, endDelta int) { e.caret.end = e.moveByGraphemes(e.caret.end, endDelta) } -// MoveStart moves the caret to the start of the current line, ensuring that the resulting +// MoveTextStart moves the caret to the start of the text. +func (e *textView) MoveTextStart(selAct selectionAction) { + caret := e.closestToRune(e.caret.end) + e.caret.start = 0 + e.caret.end = caret.runes + e.caret.xoff = -caret.x + e.updateSelection(selAct) + e.clampCursorToGraphemes() +} + +// MoveTextEnd moves the caret to the end of the text. +func (e *textView) MoveTextEnd(selAct selectionAction) { + caret := e.closestToRune(math.MaxInt) + e.caret.start = caret.runes + e.caret.xoff = fixed.I(e.params.MaxWidth) - caret.x + e.updateSelection(selAct) + e.clampCursorToGraphemes() +} + +// MoveLineStart moves the caret to the start of the current line, ensuring that the resulting // cursor position is on a grapheme cluster boundary. -func (e *textView) MoveStart(selAct selectionAction) { +func (e *textView) MoveLineStart(selAct selectionAction) { caret := e.closestToRune(e.caret.start) caret = e.closestToLineCol(caret.lineCol.line, 0) e.caret.start = caret.runes @@ -650,9 +669,9 @@ func (e *textView) MoveStart(selAct selectionAction) { e.clampCursorToGraphemes() } -// MoveEnd moves the caret to the end of the current line, ensuring that the resulting +// MoveLineEnd moves the caret to the end of the current line, ensuring that the resulting // cursor position is on a grapheme cluster boundary. -func (e *textView) MoveEnd(selAct selectionAction) { +func (e *textView) MoveLineEnd(selAct selectionAction) { caret := e.closestToRune(e.caret.start) caret = e.closestToLineCol(caret.lineCol.line, math.MaxInt) e.caret.start = caret.runes diff --git a/vendor/gioui.org/x/component/text_field.go b/vendor/gioui.org/x/component/text_field.go index 90838c25..4f9eba8f 100644 --- a/vendor/gioui.org/x/component/text_field.go +++ b/vendor/gioui.org/x/component/text_field.go @@ -131,7 +131,8 @@ func (in *TextField) Update(gtx C, th *material.Theme, hint string) { if in.click.Hovered() && !disabled { in.state = hovered } - if in.Editor.Len() > 0 { + hasContents := in.Editor.Len() > 0 + if hasContents { in.state = activated } if gtx.Source.Focused(&in.Editor) && !disabled { @@ -143,13 +144,13 @@ func (in *TextField) Update(gtx C, th *material.Theme, hint string) { if in.anim == nil { in.anim = &Progress{} } - if in.state == activated { + if in.state == activated || hasContents { in.anim.Start(gtx.Now, Forward, 0) } - if in.state == focused && in.Editor.Len() == 0 && !in.anim.Started() { + if in.state == focused && !hasContents && !in.anim.Started() { in.anim.Start(gtx.Now, Forward, duration) } - if in.state == inactive && in.Editor.Len() == 0 && in.anim.Finished() { + if in.state == inactive && !hasContents && in.anim.Finished() { in.anim.Start(gtx.Now, Reverse, duration) } if in.anim.Started() { diff --git a/vendor/gioui.org/x/outlay/grid.go b/vendor/gioui.org/x/outlay/grid.go index d124d717..e61f0442 100644 --- a/vendor/gioui.org/x/outlay/grid.go +++ b/vendor/gioui.org/x/outlay/grid.go @@ -6,6 +6,7 @@ import ( "image" "gioui.org/gesture" + "gioui.org/io/pointer" "gioui.org/layout" "gioui.org/op" "gioui.org/op/clip" @@ -133,11 +134,17 @@ func (g *Grid) Update(gtx layout.Context, rows, cols int, dimensioner Dimensione rowHeight := dimensioner(layout.Vertical, 0, gtx.Constraints.Max.Y) // Update horizontal scroll position. - hScrollDelta := g.Hscroll.Update(gtx.Metric, gtx.Source, gtx.Now, gesture.Horizontal, image.Rect(-gtx.Constraints.Max.X/2, 0, gtx.Constraints.Max.X/2, 0)) + hScrollDelta := g.Hscroll.Update(gtx.Metric, gtx.Source, gtx.Now, gesture.Horizontal, + pointer.ScrollRange{Min: -gtx.Constraints.Max.X / 2, Max: gtx.Constraints.Max.X / 2}, + pointer.ScrollRange{}, + ) g.Horizontal.Offset += hScrollDelta // Get vertical scroll info. - vScrollDelta := g.Vscroll.Update(gtx.Metric, gtx.Source, gtx.Now, gesture.Vertical, image.Rect(0, -gtx.Constraints.Max.Y/2, 0, gtx.Constraints.Max.Y/2)) + vScrollDelta := g.Vscroll.Update(gtx.Metric, gtx.Source, gtx.Now, gesture.Vertical, + pointer.ScrollRange{}, + pointer.ScrollRange{Min: -gtx.Constraints.Max.Y / 2, Max: gtx.Constraints.Max.Y / 2}, + ) g.Vertical.Offset += vScrollDelta g.Horizontal.update(gtx, layout.Horizontal, cols, gtx.Constraints.Max.X, dimensioner) diff --git a/vendor/gioui.org/x/richtext/richtext.go b/vendor/gioui.org/x/richtext/richtext.go index 8487dd8b..5cf678a4 100644 --- a/vendor/gioui.org/x/richtext/richtext.go +++ b/vendor/gioui.org/x/richtext/richtext.go @@ -61,12 +61,12 @@ func (i *InteractiveSpan) Update(gtx layout.Context) (Event, bool) { } switch e.Kind { case gesture.KindClick: + i.pressing = false if i.longPressed { i.longPressed = false } else { return Event{Type: Click, ClickData: e}, true } - i.pressing = false case gesture.KindPress: i.pressStarted = gtx.Now i.pressing = true diff --git a/vendor/github.com/golang/protobuf/jsonpb/decode.go b/vendor/github.com/golang/protobuf/jsonpb/decode.go deleted file mode 100644 index c6f66f10..00000000 --- a/vendor/github.com/golang/protobuf/jsonpb/decode.go +++ /dev/null @@ -1,531 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package jsonpb - -import ( - "encoding/json" - "errors" - "fmt" - "io" - "math" - "reflect" - "strconv" - "strings" - "time" - - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/encoding/protojson" - protoV2 "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" -) - -const wrapJSONUnmarshalV2 = false - -// UnmarshalNext unmarshals the next JSON object from d into m. -func UnmarshalNext(d *json.Decoder, m proto.Message) error { - return new(Unmarshaler).UnmarshalNext(d, m) -} - -// Unmarshal unmarshals a JSON object from r into m. -func Unmarshal(r io.Reader, m proto.Message) error { - return new(Unmarshaler).Unmarshal(r, m) -} - -// UnmarshalString unmarshals a JSON object from s into m. -func UnmarshalString(s string, m proto.Message) error { - return new(Unmarshaler).Unmarshal(strings.NewReader(s), m) -} - -// Unmarshaler is a configurable object for converting from a JSON -// representation to a protocol buffer object. -type Unmarshaler struct { - // AllowUnknownFields specifies whether to allow messages to contain - // unknown JSON fields, as opposed to failing to unmarshal. - AllowUnknownFields bool - - // AnyResolver is used to resolve the google.protobuf.Any well-known type. - // If unset, the global registry is used by default. - AnyResolver AnyResolver -} - -// 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. -// -// The JSON unmarshaling must follow the JSON to proto specification: -// -// https://developers.google.com/protocol-buffers/docs/proto3#json -// -// Deprecated: Custom types should implement protobuf reflection instead. -type JSONPBUnmarshaler interface { - UnmarshalJSONPB(*Unmarshaler, []byte) error -} - -// Unmarshal unmarshals a JSON object from r into m. -func (u *Unmarshaler) Unmarshal(r io.Reader, m proto.Message) error { - return u.UnmarshalNext(json.NewDecoder(r), m) -} - -// UnmarshalNext unmarshals the next JSON object from d into m. -func (u *Unmarshaler) UnmarshalNext(d *json.Decoder, m proto.Message) error { - if m == nil { - return errors.New("invalid nil message") - } - - // Parse the next JSON object from the stream. - raw := json.RawMessage{} - if err := d.Decode(&raw); err != nil { - return err - } - - // Check for custom unmarshalers first since they may not properly - // implement protobuf reflection that the logic below relies on. - if jsu, ok := m.(JSONPBUnmarshaler); ok { - return jsu.UnmarshalJSONPB(u, raw) - } - - mr := proto.MessageReflect(m) - - // NOTE: For historical reasons, a top-level null is treated as a noop. - // This is incorrect, but kept for compatibility. - if string(raw) == "null" && mr.Descriptor().FullName() != "google.protobuf.Value" { - return nil - } - - if wrapJSONUnmarshalV2 { - // NOTE: If input message is non-empty, we need to preserve merge semantics - // of the old jsonpb implementation. These semantics are not supported by - // the protobuf JSON specification. - isEmpty := true - mr.Range(func(protoreflect.FieldDescriptor, protoreflect.Value) bool { - isEmpty = false // at least one iteration implies non-empty - return false - }) - if !isEmpty { - // Perform unmarshaling into a newly allocated, empty message. - mr = mr.New() - - // Use a defer to copy all unmarshaled fields into the original message. - dst := proto.MessageReflect(m) - defer mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { - dst.Set(fd, v) - return true - }) - } - - // Unmarshal using the v2 JSON unmarshaler. - opts := protojson.UnmarshalOptions{ - DiscardUnknown: u.AllowUnknownFields, - } - if u.AnyResolver != nil { - opts.Resolver = anyResolver{u.AnyResolver} - } - return opts.Unmarshal(raw, mr.Interface()) - } else { - if err := u.unmarshalMessage(mr, raw); err != nil { - return err - } - return protoV2.CheckInitialized(mr.Interface()) - } -} - -func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error { - md := m.Descriptor() - fds := md.Fields() - - if jsu, ok := proto.MessageV1(m.Interface()).(JSONPBUnmarshaler); ok { - return jsu.UnmarshalJSONPB(u, in) - } - - if string(in) == "null" && md.FullName() != "google.protobuf.Value" { - return nil - } - - switch wellKnownType(md.FullName()) { - case "Any": - var jsonObject map[string]json.RawMessage - if err := json.Unmarshal(in, &jsonObject); err != nil { - return err - } - - rawTypeURL, ok := jsonObject["@type"] - if !ok { - return errors.New("Any JSON doesn't have '@type'") - } - typeURL, err := unquoteString(string(rawTypeURL)) - if err != nil { - return fmt.Errorf("can't unmarshal Any's '@type': %q", rawTypeURL) - } - m.Set(fds.ByNumber(1), protoreflect.ValueOfString(typeURL)) - - var m2 protoreflect.Message - if u.AnyResolver != nil { - mi, err := u.AnyResolver.Resolve(typeURL) - if err != nil { - return err - } - m2 = proto.MessageReflect(mi) - } else { - mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL) - if err != nil { - if err == protoregistry.NotFound { - return fmt.Errorf("could not resolve Any message type: %v", typeURL) - } - return err - } - m2 = mt.New() - } - - if wellKnownType(m2.Descriptor().FullName()) != "" { - rawValue, ok := jsonObject["value"] - if !ok { - return errors.New("Any JSON doesn't have 'value'") - } - if err := u.unmarshalMessage(m2, rawValue); err != nil { - return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err) - } - } else { - delete(jsonObject, "@type") - rawJSON, err := json.Marshal(jsonObject) - if err != nil { - return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err) - } - if err = u.unmarshalMessage(m2, rawJSON); err != nil { - return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err) - } - } - - rawWire, err := protoV2.Marshal(m2.Interface()) - if err != nil { - return fmt.Errorf("can't marshal proto %v into Any.Value: %v", typeURL, err) - } - m.Set(fds.ByNumber(2), protoreflect.ValueOfBytes(rawWire)) - return nil - case "BoolValue", "BytesValue", "StringValue", - "Int32Value", "UInt32Value", "FloatValue", - "Int64Value", "UInt64Value", "DoubleValue": - fd := fds.ByNumber(1) - v, err := u.unmarshalValue(m.NewField(fd), in, fd) - if err != nil { - return err - } - m.Set(fd, v) - return nil - case "Duration": - v, err := unquoteString(string(in)) - if err != nil { - return err - } - d, err := time.ParseDuration(v) - if err != nil { - return fmt.Errorf("bad Duration: %v", err) - } - - sec := d.Nanoseconds() / 1e9 - nsec := d.Nanoseconds() % 1e9 - m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec))) - m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec))) - return nil - case "Timestamp": - v, err := unquoteString(string(in)) - if err != nil { - return err - } - t, err := time.Parse(time.RFC3339Nano, v) - if err != nil { - return fmt.Errorf("bad Timestamp: %v", err) - } - - sec := t.Unix() - nsec := t.Nanosecond() - m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec))) - m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec))) - return nil - case "Value": - switch { - case string(in) == "null": - m.Set(fds.ByNumber(1), protoreflect.ValueOfEnum(0)) - case string(in) == "true": - m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(true)) - case string(in) == "false": - m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(false)) - case hasPrefixAndSuffix('"', in, '"'): - s, err := unquoteString(string(in)) - if err != nil { - return fmt.Errorf("unrecognized type for Value %q", in) - } - m.Set(fds.ByNumber(3), protoreflect.ValueOfString(s)) - case hasPrefixAndSuffix('[', in, ']'): - v := m.Mutable(fds.ByNumber(6)) - return u.unmarshalMessage(v.Message(), in) - case hasPrefixAndSuffix('{', in, '}'): - v := m.Mutable(fds.ByNumber(5)) - return u.unmarshalMessage(v.Message(), in) - default: - f, err := strconv.ParseFloat(string(in), 0) - if err != nil { - return fmt.Errorf("unrecognized type for Value %q", in) - } - m.Set(fds.ByNumber(2), protoreflect.ValueOfFloat64(f)) - } - return nil - case "ListValue": - var jsonArray []json.RawMessage - if err := json.Unmarshal(in, &jsonArray); err != nil { - return fmt.Errorf("bad ListValue: %v", err) - } - - lv := m.Mutable(fds.ByNumber(1)).List() - for _, raw := range jsonArray { - ve := lv.NewElement() - if err := u.unmarshalMessage(ve.Message(), raw); err != nil { - return err - } - lv.Append(ve) - } - return nil - case "Struct": - var jsonObject map[string]json.RawMessage - if err := json.Unmarshal(in, &jsonObject); err != nil { - return fmt.Errorf("bad StructValue: %v", err) - } - - mv := m.Mutable(fds.ByNumber(1)).Map() - for key, raw := range jsonObject { - kv := protoreflect.ValueOf(key).MapKey() - vv := mv.NewValue() - if err := u.unmarshalMessage(vv.Message(), raw); err != nil { - return fmt.Errorf("bad value in StructValue for key %q: %v", key, err) - } - mv.Set(kv, vv) - } - return nil - } - - var jsonObject map[string]json.RawMessage - if err := json.Unmarshal(in, &jsonObject); err != nil { - return err - } - - // Handle known fields. - for i := 0; i < fds.Len(); i++ { - fd := fds.Get(i) - if fd.IsWeak() && fd.Message().IsPlaceholder() { - continue // weak reference is not linked in - } - - // Search for any raw JSON value associated with this field. - var raw json.RawMessage - name := string(fd.Name()) - if fd.Kind() == protoreflect.GroupKind { - name = string(fd.Message().Name()) - } - if v, ok := jsonObject[name]; ok { - delete(jsonObject, name) - raw = v - } - name = string(fd.JSONName()) - if v, ok := jsonObject[name]; ok { - delete(jsonObject, name) - raw = v - } - - field := m.NewField(fd) - // Unmarshal the field value. - if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) { - continue - } - v, err := u.unmarshalValue(field, raw, fd) - if err != nil { - return err - } - m.Set(fd, v) - } - - // Handle extension fields. - for name, raw := range jsonObject { - if !strings.HasPrefix(name, "[") || !strings.HasSuffix(name, "]") { - continue - } - - // Resolve the extension field by name. - xname := protoreflect.FullName(name[len("[") : len(name)-len("]")]) - xt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname) - if xt == nil && isMessageSet(md) { - xt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append("message_set_extension")) - } - if xt == nil { - continue - } - delete(jsonObject, name) - fd := xt.TypeDescriptor() - if fd.ContainingMessage().FullName() != m.Descriptor().FullName() { - return fmt.Errorf("extension field %q does not extend message %q", xname, m.Descriptor().FullName()) - } - - field := m.NewField(fd) - // Unmarshal the field value. - if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd) && !isSingularJSONPBUnmarshaler(field, fd)) { - continue - } - v, err := u.unmarshalValue(field, raw, fd) - if err != nil { - return err - } - m.Set(fd, v) - } - - if !u.AllowUnknownFields && len(jsonObject) > 0 { - for name := range jsonObject { - return fmt.Errorf("unknown field %q in %v", name, md.FullName()) - } - } - return nil -} - -func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool { - if fd.Cardinality() == protoreflect.Repeated { - return false - } - if md := fd.Message(); md != nil { - return md.FullName() == "google.protobuf.Value" - } - if ed := fd.Enum(); ed != nil { - return ed.FullName() == "google.protobuf.NullValue" - } - return false -} - -func isSingularJSONPBUnmarshaler(v protoreflect.Value, fd protoreflect.FieldDescriptor) bool { - if fd.Message() != nil && fd.Cardinality() != protoreflect.Repeated { - _, ok := proto.MessageV1(v.Interface()).(JSONPBUnmarshaler) - return ok - } - return false -} - -func (u *Unmarshaler) unmarshalValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { - switch { - case fd.IsList(): - var jsonArray []json.RawMessage - if err := json.Unmarshal(in, &jsonArray); err != nil { - return v, err - } - lv := v.List() - for _, raw := range jsonArray { - ve, err := u.unmarshalSingularValue(lv.NewElement(), raw, fd) - if err != nil { - return v, err - } - lv.Append(ve) - } - return v, nil - case fd.IsMap(): - var jsonObject map[string]json.RawMessage - if err := json.Unmarshal(in, &jsonObject); err != nil { - return v, err - } - kfd := fd.MapKey() - vfd := fd.MapValue() - mv := v.Map() - for key, raw := range jsonObject { - var kv protoreflect.MapKey - if kfd.Kind() == protoreflect.StringKind { - kv = protoreflect.ValueOf(key).MapKey() - } else { - v, err := u.unmarshalSingularValue(kfd.Default(), []byte(key), kfd) - if err != nil { - return v, err - } - kv = v.MapKey() - } - - vv, err := u.unmarshalSingularValue(mv.NewValue(), raw, vfd) - if err != nil { - return v, err - } - mv.Set(kv, vv) - } - return v, nil - default: - return u.unmarshalSingularValue(v, in, fd) - } -} - -var nonFinite = map[string]float64{ - `"NaN"`: math.NaN(), - `"Infinity"`: math.Inf(+1), - `"-Infinity"`: math.Inf(-1), -} - -func (u *Unmarshaler) unmarshalSingularValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { - switch fd.Kind() { - case protoreflect.BoolKind: - return unmarshalValue(in, new(bool)) - case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: - return unmarshalValue(trimQuote(in), new(int32)) - case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: - return unmarshalValue(trimQuote(in), new(int64)) - case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: - return unmarshalValue(trimQuote(in), new(uint32)) - case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: - return unmarshalValue(trimQuote(in), new(uint64)) - case protoreflect.FloatKind: - if f, ok := nonFinite[string(in)]; ok { - return protoreflect.ValueOfFloat32(float32(f)), nil - } - return unmarshalValue(trimQuote(in), new(float32)) - case protoreflect.DoubleKind: - if f, ok := nonFinite[string(in)]; ok { - return protoreflect.ValueOfFloat64(float64(f)), nil - } - return unmarshalValue(trimQuote(in), new(float64)) - case protoreflect.StringKind: - return unmarshalValue(in, new(string)) - case protoreflect.BytesKind: - return unmarshalValue(in, new([]byte)) - case protoreflect.EnumKind: - if hasPrefixAndSuffix('"', in, '"') { - vd := fd.Enum().Values().ByName(protoreflect.Name(trimQuote(in))) - if vd == nil { - return v, fmt.Errorf("unknown value %q for enum %s", in, fd.Enum().FullName()) - } - return protoreflect.ValueOfEnum(vd.Number()), nil - } - return unmarshalValue(in, new(protoreflect.EnumNumber)) - case protoreflect.MessageKind, protoreflect.GroupKind: - err := u.unmarshalMessage(v.Message(), in) - return v, err - default: - panic(fmt.Sprintf("invalid kind %v", fd.Kind())) - } -} - -func unmarshalValue(in []byte, v interface{}) (protoreflect.Value, error) { - err := json.Unmarshal(in, v) - return protoreflect.ValueOf(reflect.ValueOf(v).Elem().Interface()), err -} - -func unquoteString(in string) (out string, err error) { - err = json.Unmarshal([]byte(in), &out) - return out, err -} - -func hasPrefixAndSuffix(prefix byte, in []byte, suffix byte) bool { - if len(in) >= 2 && in[0] == prefix && in[len(in)-1] == suffix { - return true - } - return false -} - -// trimQuote is like unquoteString but simply strips surrounding quotes. -// This is incorrect, but is behavior done by the legacy implementation. -func trimQuote(in []byte) []byte { - if len(in) >= 2 && in[0] == '"' && in[len(in)-1] == '"' { - in = in[1 : len(in)-1] - } - return in -} diff --git a/vendor/github.com/golang/protobuf/jsonpb/encode.go b/vendor/github.com/golang/protobuf/jsonpb/encode.go deleted file mode 100644 index e9438a93..00000000 --- a/vendor/github.com/golang/protobuf/jsonpb/encode.go +++ /dev/null @@ -1,560 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package jsonpb - -import ( - "encoding/json" - "errors" - "fmt" - "io" - "math" - "reflect" - "sort" - "strconv" - "strings" - "time" - - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/encoding/protojson" - protoV2 "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" -) - -const wrapJSONMarshalV2 = false - -// Marshaler is a configurable object for marshaling protocol buffer messages -// to the specified JSON representation. -type Marshaler struct { - // OrigName specifies whether to use the original protobuf name for fields. - OrigName bool - - // EnumsAsInts specifies whether to render enum values as integers, - // as opposed to string values. - EnumsAsInts bool - - // EmitDefaults specifies whether to render fields with zero values. - EmitDefaults bool - - // Indent controls whether the output is compact or not. - // If empty, the output is compact JSON. Otherwise, every JSON object - // entry and JSON array value will be on its own line. - // Each line will be preceded by repeated copies of Indent, where the - // number of copies is the current indentation depth. - Indent string - - // AnyResolver is used to resolve the google.protobuf.Any well-known type. - // If unset, the global registry is used by default. - AnyResolver AnyResolver -} - -// 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. -// -// The JSON marshaling must follow the proto to JSON specification: -// -// https://developers.google.com/protocol-buffers/docs/proto3#json -// -// Deprecated: Custom types should implement protobuf reflection instead. -type JSONPBMarshaler interface { - MarshalJSONPB(*Marshaler) ([]byte, error) -} - -// Marshal serializes a protobuf message as JSON into w. -func (jm *Marshaler) Marshal(w io.Writer, m proto.Message) error { - b, err := jm.marshal(m) - if len(b) > 0 { - if _, err := w.Write(b); err != nil { - return err - } - } - return err -} - -// MarshalToString serializes a protobuf message as JSON in string form. -func (jm *Marshaler) MarshalToString(m proto.Message) (string, error) { - b, err := jm.marshal(m) - if err != nil { - return "", err - } - return string(b), nil -} - -func (jm *Marshaler) marshal(m proto.Message) ([]byte, error) { - v := reflect.ValueOf(m) - if m == nil || (v.Kind() == reflect.Ptr && v.IsNil()) { - return nil, errors.New("Marshal called with nil") - } - - // Check for custom marshalers first since they may not properly - // implement protobuf reflection that the logic below relies on. - if jsm, ok := m.(JSONPBMarshaler); ok { - return jsm.MarshalJSONPB(jm) - } - - if wrapJSONMarshalV2 { - opts := protojson.MarshalOptions{ - UseProtoNames: jm.OrigName, - UseEnumNumbers: jm.EnumsAsInts, - EmitUnpopulated: jm.EmitDefaults, - Indent: jm.Indent, - } - if jm.AnyResolver != nil { - opts.Resolver = anyResolver{jm.AnyResolver} - } - return opts.Marshal(proto.MessageReflect(m).Interface()) - } else { - // Check for unpopulated required fields first. - m2 := proto.MessageReflect(m) - if err := protoV2.CheckInitialized(m2.Interface()); err != nil { - return nil, err - } - - w := jsonWriter{Marshaler: jm} - err := w.marshalMessage(m2, "", "") - return w.buf, err - } -} - -type jsonWriter struct { - *Marshaler - buf []byte -} - -func (w *jsonWriter) write(s string) { - w.buf = append(w.buf, s...) -} - -func (w *jsonWriter) marshalMessage(m protoreflect.Message, indent, typeURL string) error { - if jsm, ok := proto.MessageV1(m.Interface()).(JSONPBMarshaler); ok { - b, err := jsm.MarshalJSONPB(w.Marshaler) - 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", m.Interface(), 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 - } - } - w.write(string(b)) - return nil - } - - md := m.Descriptor() - fds := md.Fields() - - // Handle well-known types. - const secondInNanos = int64(time.Second / time.Nanosecond) - switch wellKnownType(md.FullName()) { - case "Any": - return w.marshalAny(m, indent) - case "BoolValue", "BytesValue", "StringValue", - "Int32Value", "UInt32Value", "FloatValue", - "Int64Value", "UInt64Value", "DoubleValue": - fd := fds.ByNumber(1) - return w.marshalValue(fd, m.Get(fd), indent) - case "Duration": - const maxSecondsInDuration = 315576000000 - // "Generated output always contains 0, 3, 6, or 9 fractional digits, - // depending on required precision." - s := m.Get(fds.ByNumber(1)).Int() - ns := m.Get(fds.ByNumber(2)).Int() - if s < -maxSecondsInDuration || s > maxSecondsInDuration { - return fmt.Errorf("seconds out of range %v", s) - } - if ns <= -secondInNanos || ns >= secondInNanos { - return fmt.Errorf("ns out of range (%v, %v)", -secondInNanos, secondInNanos) - } - if (s > 0 && ns < 0) || (s < 0 && ns > 0) { - return errors.New("signs of seconds and nanos do not match") - } - var sign string - if s < 0 || ns < 0 { - sign, s, ns = "-", -1*s, -1*ns - } - x := fmt.Sprintf("%s%d.%09d", sign, s, ns) - x = strings.TrimSuffix(x, "000") - x = strings.TrimSuffix(x, "000") - x = strings.TrimSuffix(x, ".000") - w.write(fmt.Sprintf(`"%vs"`, x)) - return nil - case "Timestamp": - // "RFC 3339, where generated output will always be Z-normalized - // and uses 0, 3, 6 or 9 fractional digits." - s := m.Get(fds.ByNumber(1)).Int() - ns := m.Get(fds.ByNumber(2)).Int() - if ns < 0 || ns >= secondInNanos { - return fmt.Errorf("ns out of range [0, %v)", secondInNanos) - } - 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") - x = strings.TrimSuffix(x, ".000") - w.write(fmt.Sprintf(`"%vZ"`, x)) - return nil - case "Value": - // JSON value; which is a null, number, string, bool, object, or array. - od := md.Oneofs().Get(0) - fd := m.WhichOneof(od) - if fd == nil { - return errors.New("nil Value") - } - return w.marshalValue(fd, m.Get(fd), indent) - case "Struct", "ListValue": - // JSON object or array. - fd := fds.ByNumber(1) - return w.marshalValue(fd, m.Get(fd), indent) - } - - w.write("{") - if w.Indent != "" { - w.write("\n") - } - - firstField := true - if typeURL != "" { - if err := w.marshalTypeURL(indent, typeURL); err != nil { - return err - } - firstField = false - } - - for i := 0; i < fds.Len(); { - fd := fds.Get(i) - if od := fd.ContainingOneof(); od != nil { - fd = m.WhichOneof(od) - i += od.Fields().Len() - if fd == nil { - continue - } - } else { - i++ - } - - v := m.Get(fd) - - if !m.Has(fd) { - if !w.EmitDefaults || fd.ContainingOneof() != nil { - continue - } - if fd.Cardinality() != protoreflect.Repeated && (fd.Message() != nil || fd.Syntax() == protoreflect.Proto2) { - v = protoreflect.Value{} // use "null" for singular messages or proto2 scalars - } - } - - if !firstField { - w.writeComma() - } - if err := w.marshalField(fd, v, indent); err != nil { - return err - } - firstField = false - } - - // Handle proto2 extensions. - if md.ExtensionRanges().Len() > 0 { - // Collect a sorted list of all extension descriptor and values. - type ext struct { - desc protoreflect.FieldDescriptor - val protoreflect.Value - } - var exts []ext - m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { - if fd.IsExtension() { - exts = append(exts, ext{fd, v}) - } - return true - }) - sort.Slice(exts, func(i, j int) bool { - return exts[i].desc.Number() < exts[j].desc.Number() - }) - - for _, ext := range exts { - if !firstField { - w.writeComma() - } - if err := w.marshalField(ext.desc, ext.val, indent); err != nil { - return err - } - firstField = false - } - } - - if w.Indent != "" { - w.write("\n") - w.write(indent) - } - w.write("}") - return nil -} - -func (w *jsonWriter) writeComma() { - if w.Indent != "" { - w.write(",\n") - } else { - w.write(",") - } -} - -func (w *jsonWriter) marshalAny(m protoreflect.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." - md := m.Descriptor() - typeURL := m.Get(md.Fields().ByNumber(1)).String() - rawVal := m.Get(md.Fields().ByNumber(2)).Bytes() - - var m2 protoreflect.Message - if w.AnyResolver != nil { - mi, err := w.AnyResolver.Resolve(typeURL) - if err != nil { - return err - } - m2 = proto.MessageReflect(mi) - } else { - mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL) - if err != nil { - return err - } - m2 = mt.New() - } - - if err := protoV2.Unmarshal(rawVal, m2.Interface()); err != nil { - return err - } - - if wellKnownType(m2.Descriptor().FullName()) == "" { - return w.marshalMessage(m2, indent, typeURL) - } - - w.write("{") - if w.Indent != "" { - w.write("\n") - } - if err := w.marshalTypeURL(indent, typeURL); err != nil { - return err - } - w.writeComma() - if w.Indent != "" { - w.write(indent) - w.write(w.Indent) - w.write(`"value": `) - } else { - w.write(`"value":`) - } - if err := w.marshalMessage(m2, indent+w.Indent, ""); err != nil { - return err - } - if w.Indent != "" { - w.write("\n") - w.write(indent) - } - w.write("}") - return nil -} - -func (w *jsonWriter) marshalTypeURL(indent, typeURL string) error { - if w.Indent != "" { - w.write(indent) - w.write(w.Indent) - } - w.write(`"@type":`) - if w.Indent != "" { - w.write(" ") - } - b, err := json.Marshal(typeURL) - if err != nil { - return err - } - w.write(string(b)) - return nil -} - -// marshalField writes field description and value to the Writer. -func (w *jsonWriter) marshalField(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error { - if w.Indent != "" { - w.write(indent) - w.write(w.Indent) - } - w.write(`"`) - switch { - case fd.IsExtension(): - // For message set, use the fname of the message as the extension name. - name := string(fd.FullName()) - if isMessageSet(fd.ContainingMessage()) { - name = strings.TrimSuffix(name, ".message_set_extension") - } - - w.write("[" + name + "]") - case w.OrigName: - name := string(fd.Name()) - if fd.Kind() == protoreflect.GroupKind { - name = string(fd.Message().Name()) - } - w.write(name) - default: - w.write(string(fd.JSONName())) - } - w.write(`":`) - if w.Indent != "" { - w.write(" ") - } - return w.marshalValue(fd, v, indent) -} - -func (w *jsonWriter) marshalValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error { - switch { - case fd.IsList(): - w.write("[") - comma := "" - lv := v.List() - for i := 0; i < lv.Len(); i++ { - w.write(comma) - if w.Indent != "" { - w.write("\n") - w.write(indent) - w.write(w.Indent) - w.write(w.Indent) - } - if err := w.marshalSingularValue(fd, lv.Get(i), indent+w.Indent); err != nil { - return err - } - comma = "," - } - if w.Indent != "" { - w.write("\n") - w.write(indent) - w.write(w.Indent) - } - w.write("]") - return nil - case fd.IsMap(): - kfd := fd.MapKey() - vfd := fd.MapValue() - mv := v.Map() - - // Collect a sorted list of all map keys and values. - type entry struct{ key, val protoreflect.Value } - var entries []entry - mv.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool { - entries = append(entries, entry{k.Value(), v}) - return true - }) - sort.Slice(entries, func(i, j int) bool { - switch kfd.Kind() { - case protoreflect.BoolKind: - return !entries[i].key.Bool() && entries[j].key.Bool() - case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind, protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: - return entries[i].key.Int() < entries[j].key.Int() - case protoreflect.Uint32Kind, protoreflect.Fixed32Kind, protoreflect.Uint64Kind, protoreflect.Fixed64Kind: - return entries[i].key.Uint() < entries[j].key.Uint() - case protoreflect.StringKind: - return entries[i].key.String() < entries[j].key.String() - default: - panic("invalid kind") - } - }) - - w.write(`{`) - comma := "" - for _, entry := range entries { - w.write(comma) - if w.Indent != "" { - w.write("\n") - w.write(indent) - w.write(w.Indent) - w.write(w.Indent) - } - - s := fmt.Sprint(entry.key.Interface()) - b, err := json.Marshal(s) - if err != nil { - return err - } - w.write(string(b)) - - w.write(`:`) - if w.Indent != "" { - w.write(` `) - } - - if err := w.marshalSingularValue(vfd, entry.val, indent+w.Indent); err != nil { - return err - } - comma = "," - } - if w.Indent != "" { - w.write("\n") - w.write(indent) - w.write(w.Indent) - } - w.write(`}`) - return nil - default: - return w.marshalSingularValue(fd, v, indent) - } -} - -func (w *jsonWriter) marshalSingularValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error { - switch { - case !v.IsValid(): - w.write("null") - return nil - case fd.Message() != nil: - return w.marshalMessage(v.Message(), indent+w.Indent, "") - case fd.Enum() != nil: - if fd.Enum().FullName() == "google.protobuf.NullValue" { - w.write("null") - return nil - } - - vd := fd.Enum().Values().ByNumber(v.Enum()) - if vd == nil || w.EnumsAsInts { - w.write(strconv.Itoa(int(v.Enum()))) - } else { - w.write(`"` + string(vd.Name()) + `"`) - } - return nil - default: - switch v.Interface().(type) { - case float32, float64: - switch { - case math.IsInf(v.Float(), +1): - w.write(`"Infinity"`) - return nil - case math.IsInf(v.Float(), -1): - w.write(`"-Infinity"`) - return nil - case math.IsNaN(v.Float()): - w.write(`"NaN"`) - return nil - } - case int64, uint64: - w.write(fmt.Sprintf(`"%d"`, v.Interface())) - return nil - } - - b, err := json.Marshal(v.Interface()) - if err != nil { - return err - } - w.write(string(b)) - return nil - } -} diff --git a/vendor/github.com/golang/protobuf/jsonpb/json.go b/vendor/github.com/golang/protobuf/jsonpb/json.go deleted file mode 100644 index 480e2448..00000000 --- a/vendor/github.com/golang/protobuf/jsonpb/json.go +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package jsonpb provides functionality to marshal and unmarshal between a -// protocol buffer message and JSON. It follows the specification at -// https://developers.google.com/protocol-buffers/docs/proto3#json. -// -// Do not rely on the default behavior of the standard encoding/json package -// when called on generated message types as it does not operate correctly. -// -// Deprecated: Use the "google.golang.org/protobuf/encoding/protojson" -// package instead. -package jsonpb - -import ( - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" - "google.golang.org/protobuf/runtime/protoimpl" -) - -// 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) -} - -type anyResolver struct{ AnyResolver } - -func (r anyResolver) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) { - return r.FindMessageByURL(string(message)) -} - -func (r anyResolver) FindMessageByURL(url string) (protoreflect.MessageType, error) { - m, err := r.Resolve(url) - if err != nil { - return nil, err - } - return protoimpl.X.MessageTypeOf(m), nil -} - -func (r anyResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) { - return protoregistry.GlobalTypes.FindExtensionByName(field) -} - -func (r anyResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) { - return protoregistry.GlobalTypes.FindExtensionByNumber(message, field) -} - -func wellKnownType(s protoreflect.FullName) string { - if s.Parent() == "google.protobuf" { - switch s.Name() { - case "Empty", "Any", - "BoolValue", "BytesValue", "StringValue", - "Int32Value", "UInt32Value", "FloatValue", - "Int64Value", "UInt64Value", "DoubleValue", - "Duration", "Timestamp", - "NullValue", "Struct", "Value", "ListValue": - return string(s.Name()) - } - } - return "" -} - -func isMessageSet(md protoreflect.MessageDescriptor) bool { - ms, ok := md.(interface{ IsMessageSet() bool }) - return ok && ms.IsMessageSet() -} diff --git a/vendor/github.com/jhump/protoreflect/codec/codec.go b/vendor/github.com/jhump/protoreflect/codec/codec.go deleted file mode 100644 index 7e5c5684..00000000 --- a/vendor/github.com/jhump/protoreflect/codec/codec.go +++ /dev/null @@ -1,218 +0,0 @@ -package codec - -import ( - "io" - - "github.com/golang/protobuf/proto" - - "github.com/jhump/protoreflect/internal/codec" -) - -// ErrOverflow is returned when an integer is too large to be represented. -var ErrOverflow = codec.ErrOverflow - -// ErrBadWireType is returned when decoding a wire-type from a buffer that -// is not valid. -var ErrBadWireType = codec.ErrBadWireType - -// NB: much of the implementation is in an internal package, to avoid an import -// cycle between this codec package and the desc package. We export it from -// this package, but we can't use a type alias because we also need to add -// methods to it, to broaden the exposed API. - -// Buffer is a reader and a writer that wraps a slice of bytes and also -// provides API for decoding and encoding the protobuf binary format. -// -// Its operation is similar to that of a bytes.Buffer: writing pushes -// data to the end of the buffer while reading pops data from the head -// of the buffer. So the same buffer can be used to both read and write. -type Buffer codec.Buffer - -// NewBuffer creates a new buffer with the given slice of bytes as the -// buffer's initial contents. -func NewBuffer(buf []byte) *Buffer { - return (*Buffer)(codec.NewBuffer(buf)) -} - -// SetDeterministic sets this buffer to encode messages deterministically. This -// is useful for tests. But the overhead is non-zero, so it should not likely be -// used outside of tests. When true, map fields in a message must have their -// keys sorted before serialization to ensure deterministic output. Otherwise, -// values in a map field will be serialized in map iteration order. -func (cb *Buffer) SetDeterministic(deterministic bool) { - (*codec.Buffer)(cb).SetDeterministic(deterministic) -} - -// IsDeterministic returns whether or not this buffer is configured to encode -// messages deterministically. -func (cb *Buffer) IsDeterministic() bool { - return (*codec.Buffer)(cb).IsDeterministic() -} - -// Reset resets this buffer back to empty. Any subsequent writes/encodes -// to the buffer will allocate a new backing slice of bytes. -func (cb *Buffer) Reset() { - (*codec.Buffer)(cb).Reset() -} - -// Bytes returns the slice of bytes remaining in the buffer. Note that -// this does not perform a copy: if the contents of the returned slice -// are modified, the modifications will be visible to subsequent reads -// via the buffer. -func (cb *Buffer) Bytes() []byte { - return (*codec.Buffer)(cb).Bytes() -} - -// String returns the remaining bytes in the buffer as a string. -func (cb *Buffer) String() string { - return (*codec.Buffer)(cb).String() -} - -// EOF returns true if there are no more bytes remaining to read. -func (cb *Buffer) EOF() bool { - return (*codec.Buffer)(cb).EOF() -} - -// Skip attempts to skip the given number of bytes in the input. If -// the input has fewer bytes than the given count, io.ErrUnexpectedEOF -// is returned and the buffer is unchanged. Otherwise, the given number -// of bytes are skipped and nil is returned. -func (cb *Buffer) Skip(count int) error { - return (*codec.Buffer)(cb).Skip(count) - -} - -// Len returns the remaining number of bytes in the buffer. -func (cb *Buffer) Len() int { - return (*codec.Buffer)(cb).Len() -} - -// Read implements the io.Reader interface. If there are no bytes -// remaining in the buffer, it will return 0, io.EOF. Otherwise, -// it reads max(len(dest), cb.Len()) bytes from input and copies -// them into dest. It returns the number of bytes copied and a nil -// error in this case. -func (cb *Buffer) Read(dest []byte) (int, error) { - return (*codec.Buffer)(cb).Read(dest) -} - -var _ io.Reader = (*Buffer)(nil) - -// Write implements the io.Writer interface. It always returns -// len(data), nil. -func (cb *Buffer) Write(data []byte) (int, error) { - return (*codec.Buffer)(cb).Write(data) -} - -var _ io.Writer = (*Buffer)(nil) - -// DecodeVarint reads a varint-encoded integer from the Buffer. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func (cb *Buffer) DecodeVarint() (uint64, error) { - return (*codec.Buffer)(cb).DecodeVarint() -} - -// DecodeTagAndWireType decodes a field tag and wire type from input. -// This reads a varint and then extracts the two fields from the varint -// value read. -func (cb *Buffer) DecodeTagAndWireType() (tag int32, wireType int8, err error) { - return (*codec.Buffer)(cb).DecodeTagAndWireType() -} - -// DecodeFixed64 reads a 64-bit integer from the Buffer. -// This is the format for the -// fixed64, sfixed64, and double protocol buffer types. -func (cb *Buffer) DecodeFixed64() (x uint64, err error) { - return (*codec.Buffer)(cb).DecodeFixed64() -} - -// DecodeFixed32 reads a 32-bit integer from the Buffer. -// This is the format for the -// fixed32, sfixed32, and float protocol buffer types. -func (cb *Buffer) DecodeFixed32() (x uint64, err error) { - return (*codec.Buffer)(cb).DecodeFixed32() -} - -// DecodeRawBytes reads a count-delimited byte buffer from the Buffer. -// This is the format used for the bytes protocol buffer -// type and for embedded messages. -func (cb *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) { - return (*codec.Buffer)(cb).DecodeRawBytes(alloc) -} - -// ReadGroup reads the input until a "group end" tag is found -// and returns the data up to that point. Subsequent reads from -// the buffer will read data after the group end tag. If alloc -// is true, the data is copied to a new slice before being returned. -// Otherwise, the returned slice is a view into the buffer's -// underlying byte slice. -// -// This function correctly handles nested groups: if a "group start" -// tag is found, then that group's end tag will be included in the -// returned data. -func (cb *Buffer) ReadGroup(alloc bool) ([]byte, error) { - return (*codec.Buffer)(cb).ReadGroup(alloc) -} - -// SkipGroup is like ReadGroup, except that it discards the -// data and just advances the buffer to point to the input -// right *after* the "group end" tag. -func (cb *Buffer) SkipGroup() error { - return (*codec.Buffer)(cb).SkipGroup() -} - -// SkipField attempts to skip the value of a field with the given wire -// type. When consuming a protobuf-encoded stream, it can be called immediately -// after DecodeTagAndWireType to discard the subsequent data for the field. -func (cb *Buffer) SkipField(wireType int8) error { - return (*codec.Buffer)(cb).SkipField(wireType) -} - -// EncodeVarint writes a varint-encoded integer to the Buffer. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func (cb *Buffer) EncodeVarint(x uint64) error { - return (*codec.Buffer)(cb).EncodeVarint(x) -} - -// EncodeTagAndWireType encodes the given field tag and wire type to the -// buffer. This combines the two values and then writes them as a varint. -func (cb *Buffer) EncodeTagAndWireType(tag int32, wireType int8) error { - return (*codec.Buffer)(cb).EncodeTagAndWireType(tag, wireType) -} - -// EncodeFixed64 writes a 64-bit integer to the Buffer. -// This is the format for the -// fixed64, sfixed64, and double protocol buffer types. -func (cb *Buffer) EncodeFixed64(x uint64) error { - return (*codec.Buffer)(cb).EncodeFixed64(x) - -} - -// EncodeFixed32 writes a 32-bit integer to the Buffer. -// This is the format for the -// fixed32, sfixed32, and float protocol buffer types. -func (cb *Buffer) EncodeFixed32(x uint64) error { - return (*codec.Buffer)(cb).EncodeFixed32(x) -} - -// EncodeRawBytes writes a count-delimited byte buffer to the Buffer. -// This is the format used for the bytes protocol buffer -// type and for embedded messages. -func (cb *Buffer) EncodeRawBytes(b []byte) error { - return (*codec.Buffer)(cb).EncodeRawBytes(b) -} - -// EncodeMessage writes the given message to the buffer. -func (cb *Buffer) EncodeMessage(pm proto.Message) error { - return (*codec.Buffer)(cb).EncodeMessage(pm) -} - -// EncodeDelimitedMessage writes the given message to the buffer with a -// varint-encoded length prefix (the delimiter). -func (cb *Buffer) EncodeDelimitedMessage(pm proto.Message) error { - return (*codec.Buffer)(cb).EncodeDelimitedMessage(pm) -} diff --git a/vendor/github.com/jhump/protoreflect/codec/decode_fields.go b/vendor/github.com/jhump/protoreflect/codec/decode_fields.go deleted file mode 100644 index 0edb817c..00000000 --- a/vendor/github.com/jhump/protoreflect/codec/decode_fields.go +++ /dev/null @@ -1,318 +0,0 @@ -package codec - -import ( - "errors" - "fmt" - "io" - "math" - - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/types/descriptorpb" - - "github.com/jhump/protoreflect/desc" -) - -var varintTypes = map[descriptorpb.FieldDescriptorProto_Type]bool{} -var fixed32Types = map[descriptorpb.FieldDescriptorProto_Type]bool{} -var fixed64Types = map[descriptorpb.FieldDescriptorProto_Type]bool{} - -func init() { - varintTypes[descriptorpb.FieldDescriptorProto_TYPE_BOOL] = true - varintTypes[descriptorpb.FieldDescriptorProto_TYPE_INT32] = true - varintTypes[descriptorpb.FieldDescriptorProto_TYPE_INT64] = true - varintTypes[descriptorpb.FieldDescriptorProto_TYPE_UINT32] = true - varintTypes[descriptorpb.FieldDescriptorProto_TYPE_UINT64] = true - varintTypes[descriptorpb.FieldDescriptorProto_TYPE_SINT32] = true - varintTypes[descriptorpb.FieldDescriptorProto_TYPE_SINT64] = true - varintTypes[descriptorpb.FieldDescriptorProto_TYPE_ENUM] = true - - fixed32Types[descriptorpb.FieldDescriptorProto_TYPE_FIXED32] = true - fixed32Types[descriptorpb.FieldDescriptorProto_TYPE_SFIXED32] = true - fixed32Types[descriptorpb.FieldDescriptorProto_TYPE_FLOAT] = true - - fixed64Types[descriptorpb.FieldDescriptorProto_TYPE_FIXED64] = true - fixed64Types[descriptorpb.FieldDescriptorProto_TYPE_SFIXED64] = true - fixed64Types[descriptorpb.FieldDescriptorProto_TYPE_DOUBLE] = true -} - -// ErrWireTypeEndGroup is returned from DecodeFieldValue if the tag and wire-type -// it reads indicates an end-group marker. -var ErrWireTypeEndGroup = errors.New("unexpected wire type: end group") - -// MessageFactory is used to instantiate messages when DecodeFieldValue needs to -// decode a message value. -// -// Also see MessageFactory in "github.com/jhump/protoreflect/dynamic", which -// implements this interface. -type MessageFactory interface { - NewMessage(md *desc.MessageDescriptor) proto.Message -} - -// UnknownField represents a field that was parsed from the binary wire -// format for a message, but was not a recognized field number. Enough -// information is preserved so that re-serializing the message won't lose -// any of the unrecognized data. -type UnknownField struct { - // The tag number for the unrecognized field. - Tag int32 - - // Encoding indicates how the unknown field was encoded on the wire. If it - // is proto.WireBytes or proto.WireGroupStart then Contents will be set to - // the raw bytes. If it is proto.WireTypeFixed32 then the data is in the least - // significant 32 bits of Value. Otherwise, the data is in all 64 bits of - // Value. - Encoding int8 - Contents []byte - Value uint64 -} - -// DecodeZigZag32 decodes a signed 32-bit integer from the given -// zig-zag encoded value. -func DecodeZigZag32(v uint64) int32 { - return int32((uint32(v) >> 1) ^ uint32((int32(v&1)<<31)>>31)) -} - -// DecodeZigZag64 decodes a signed 64-bit integer from the given -// zig-zag encoded value. -func DecodeZigZag64(v uint64) int64 { - return int64((v >> 1) ^ uint64((int64(v&1)<<63)>>63)) -} - -// DecodeFieldValue will read a field value from the buffer and return its -// value and the corresponding field descriptor. The given function is used -// to lookup a field descriptor by tag number. The given factory is used to -// instantiate a message if the field value is (or contains) a message value. -// -// On error, the field descriptor and value are typically nil. However, if the -// error returned is ErrWireTypeEndGroup, the returned value will indicate any -// tag number encoded in the end-group marker. -// -// If the field descriptor returned is nil, that means that the given function -// returned nil. This is expected to happen for unrecognized tag numbers. In -// that case, no error is returned, and the value will be an UnknownField. -func (cb *Buffer) DecodeFieldValue(fieldFinder func(int32) *desc.FieldDescriptor, fact MessageFactory) (*desc.FieldDescriptor, interface{}, error) { - if cb.EOF() { - return nil, nil, io.EOF - } - tagNumber, wireType, err := cb.DecodeTagAndWireType() - if err != nil { - return nil, nil, err - } - if wireType == proto.WireEndGroup { - return nil, tagNumber, ErrWireTypeEndGroup - } - fd := fieldFinder(tagNumber) - if fd == nil { - val, err := cb.decodeUnknownField(tagNumber, wireType) - return nil, val, err - } - val, err := cb.decodeKnownField(fd, wireType, fact) - return fd, val, err -} - -// DecodeScalarField extracts a properly-typed value from v. The returned value's -// type depends on the given field descriptor type. It will be the same type as -// generated structs use for the field descriptor's type. Enum types will return -// an int32. If the given field type uses length-delimited encoding (nested -// messages, bytes, and strings), an error is returned. -func DecodeScalarField(fd *desc.FieldDescriptor, v uint64) (interface{}, error) { - switch fd.GetType() { - case descriptorpb.FieldDescriptorProto_TYPE_BOOL: - return v != 0, nil - case descriptorpb.FieldDescriptorProto_TYPE_UINT32, - descriptorpb.FieldDescriptorProto_TYPE_FIXED32: - if v > math.MaxUint32 { - return nil, ErrOverflow - } - return uint32(v), nil - - case descriptorpb.FieldDescriptorProto_TYPE_INT32, - descriptorpb.FieldDescriptorProto_TYPE_ENUM: - s := int64(v) - if s > math.MaxInt32 || s < math.MinInt32 { - return nil, ErrOverflow - } - return int32(s), nil - - case descriptorpb.FieldDescriptorProto_TYPE_SFIXED32: - if v > math.MaxUint32 { - return nil, ErrOverflow - } - return int32(v), nil - - case descriptorpb.FieldDescriptorProto_TYPE_SINT32: - if v > math.MaxUint32 { - return nil, ErrOverflow - } - return DecodeZigZag32(v), nil - - case descriptorpb.FieldDescriptorProto_TYPE_UINT64, - descriptorpb.FieldDescriptorProto_TYPE_FIXED64: - return v, nil - - case descriptorpb.FieldDescriptorProto_TYPE_INT64, - descriptorpb.FieldDescriptorProto_TYPE_SFIXED64: - return int64(v), nil - - case descriptorpb.FieldDescriptorProto_TYPE_SINT64: - return DecodeZigZag64(v), nil - - case descriptorpb.FieldDescriptorProto_TYPE_FLOAT: - if v > math.MaxUint32 { - return nil, ErrOverflow - } - return math.Float32frombits(uint32(v)), nil - - case descriptorpb.FieldDescriptorProto_TYPE_DOUBLE: - return math.Float64frombits(v), nil - - default: - // bytes, string, message, and group cannot be represented as a simple numeric value - return nil, fmt.Errorf("bad input; field %s requires length-delimited wire type", fd.GetFullyQualifiedName()) - } -} - -// DecodeLengthDelimitedField extracts a properly-typed value from bytes. The -// returned value's type will usually be []byte, string, or, for nested messages, -// the type returned from the given message factory. However, since repeated -// scalar fields can be length-delimited, when they used packed encoding, it can -// also return an []interface{}, where each element is a scalar value. Furthermore, -// it could return a scalar type, not in a slice, if the given field descriptor is -// not repeated. This is to support cases where a field is changed from optional -// to repeated. New code may emit a packed repeated representation, but old code -// still expects a single scalar value. In this case, if the actual data in bytes -// contains multiple values, only the last value is returned. -func DecodeLengthDelimitedField(fd *desc.FieldDescriptor, bytes []byte, mf MessageFactory) (interface{}, error) { - switch { - case fd.GetType() == descriptorpb.FieldDescriptorProto_TYPE_BYTES: - return bytes, nil - - case fd.GetType() == descriptorpb.FieldDescriptorProto_TYPE_STRING: - return string(bytes), nil - - case fd.GetType() == descriptorpb.FieldDescriptorProto_TYPE_MESSAGE || - fd.GetType() == descriptorpb.FieldDescriptorProto_TYPE_GROUP: - msg := mf.NewMessage(fd.GetMessageType()) - err := proto.Unmarshal(bytes, msg) - if err != nil { - return nil, err - } else { - return msg, nil - } - - default: - // even if the field is not repeated or not packed, we still parse it as such for - // backwards compatibility (e.g. message we are de-serializing could have been both - // repeated and packed at the time of serialization) - packedBuf := NewBuffer(bytes) - var slice []interface{} - var val interface{} - for !packedBuf.EOF() { - var v uint64 - var err error - if varintTypes[fd.GetType()] { - v, err = packedBuf.DecodeVarint() - } else if fixed32Types[fd.GetType()] { - v, err = packedBuf.DecodeFixed32() - } else if fixed64Types[fd.GetType()] { - v, err = packedBuf.DecodeFixed64() - } else { - return nil, fmt.Errorf("bad input; cannot parse length-delimited wire type for field %s", fd.GetFullyQualifiedName()) - } - if err != nil { - return nil, err - } - val, err = DecodeScalarField(fd, v) - if err != nil { - return nil, err - } - if fd.IsRepeated() { - slice = append(slice, val) - } - } - if fd.IsRepeated() { - return slice, nil - } else { - // if not a repeated field, last value wins - return val, nil - } - } -} - -func (b *Buffer) decodeKnownField(fd *desc.FieldDescriptor, encoding int8, fact MessageFactory) (interface{}, error) { - var val interface{} - var err error - switch encoding { - case proto.WireFixed32: - var num uint64 - num, err = b.DecodeFixed32() - if err == nil { - val, err = DecodeScalarField(fd, num) - } - case proto.WireFixed64: - var num uint64 - num, err = b.DecodeFixed64() - if err == nil { - val, err = DecodeScalarField(fd, num) - } - case proto.WireVarint: - var num uint64 - num, err = b.DecodeVarint() - if err == nil { - val, err = DecodeScalarField(fd, num) - } - - case proto.WireBytes: - alloc := fd.GetType() == descriptorpb.FieldDescriptorProto_TYPE_BYTES - var raw []byte - raw, err = b.DecodeRawBytes(alloc) - if err == nil { - val, err = DecodeLengthDelimitedField(fd, raw, fact) - } - - case proto.WireStartGroup: - if fd.GetMessageType() == nil { - return nil, fmt.Errorf("cannot parse field %s from group-encoded wire type", fd.GetFullyQualifiedName()) - } - msg := fact.NewMessage(fd.GetMessageType()) - var data []byte - data, err = b.ReadGroup(false) - if err == nil { - err = proto.Unmarshal(data, msg) - if err == nil { - val = msg - } - } - - default: - return nil, ErrBadWireType - } - if err != nil { - return nil, err - } - - return val, nil -} - -func (b *Buffer) decodeUnknownField(tagNumber int32, encoding int8) (interface{}, error) { - u := UnknownField{Tag: tagNumber, Encoding: encoding} - var err error - switch encoding { - case proto.WireFixed32: - u.Value, err = b.DecodeFixed32() - case proto.WireFixed64: - u.Value, err = b.DecodeFixed64() - case proto.WireVarint: - u.Value, err = b.DecodeVarint() - case proto.WireBytes: - u.Contents, err = b.DecodeRawBytes(true) - case proto.WireStartGroup: - u.Contents, err = b.ReadGroup(true) - default: - err = ErrBadWireType - } - if err != nil { - return nil, err - } - return u, nil -} diff --git a/vendor/github.com/jhump/protoreflect/codec/doc.go b/vendor/github.com/jhump/protoreflect/codec/doc.go deleted file mode 100644 index f76499f6..00000000 --- a/vendor/github.com/jhump/protoreflect/codec/doc.go +++ /dev/null @@ -1,7 +0,0 @@ -// Package codec contains a reader/write type that assists with encoding -// and decoding protobuf's binary representation. -// -// The code in this package began as a fork of proto.Buffer but provides -// additional API to make it more useful to code that needs to dynamically -// process or produce the protobuf binary format. -package codec diff --git a/vendor/github.com/jhump/protoreflect/codec/encode_fields.go b/vendor/github.com/jhump/protoreflect/codec/encode_fields.go deleted file mode 100644 index 280f730f..00000000 --- a/vendor/github.com/jhump/protoreflect/codec/encode_fields.go +++ /dev/null @@ -1,288 +0,0 @@ -package codec - -import ( - "fmt" - "math" - "reflect" - "sort" - - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/types/descriptorpb" - - "github.com/jhump/protoreflect/desc" -) - -// EncodeZigZag64 does zig-zag encoding to convert the given -// signed 64-bit integer into a form that can be expressed -// efficiently as a varint, even for negative values. -func EncodeZigZag64(v int64) uint64 { - return (uint64(v) << 1) ^ uint64(v>>63) -} - -// EncodeZigZag32 does zig-zag encoding to convert the given -// signed 32-bit integer into a form that can be expressed -// efficiently as a varint, even for negative values. -func EncodeZigZag32(v int32) uint64 { - return uint64((uint32(v) << 1) ^ uint32((v >> 31))) -} - -func (cb *Buffer) EncodeFieldValue(fd *desc.FieldDescriptor, val interface{}) error { - if fd.IsMap() { - mp := val.(map[interface{}]interface{}) - entryType := fd.GetMessageType() - keyType := entryType.FindFieldByNumber(1) - valType := entryType.FindFieldByNumber(2) - var entryBuffer Buffer - if cb.IsDeterministic() { - entryBuffer.SetDeterministic(true) - keys := make([]interface{}, 0, len(mp)) - for k := range mp { - keys = append(keys, k) - } - sort.Sort(sortable(keys)) - for _, k := range keys { - v := mp[k] - entryBuffer.Reset() - if err := entryBuffer.encodeFieldElement(keyType, k); err != nil { - return err - } - rv := reflect.ValueOf(v) - if rv.Kind() != reflect.Ptr || !rv.IsNil() { - if err := entryBuffer.encodeFieldElement(valType, v); err != nil { - return err - } - } - if err := cb.EncodeTagAndWireType(fd.GetNumber(), proto.WireBytes); err != nil { - return err - } - if err := cb.EncodeRawBytes(entryBuffer.Bytes()); err != nil { - return err - } - } - } else { - for k, v := range mp { - entryBuffer.Reset() - if err := entryBuffer.encodeFieldElement(keyType, k); err != nil { - return err - } - rv := reflect.ValueOf(v) - if rv.Kind() != reflect.Ptr || !rv.IsNil() { - if err := entryBuffer.encodeFieldElement(valType, v); err != nil { - return err - } - } - if err := cb.EncodeTagAndWireType(fd.GetNumber(), proto.WireBytes); err != nil { - return err - } - if err := cb.EncodeRawBytes(entryBuffer.Bytes()); err != nil { - return err - } - } - } - return nil - } else if fd.IsRepeated() { - sl := val.([]interface{}) - wt, err := getWireType(fd.GetType()) - if err != nil { - return err - } - if isPacked(fd) && len(sl) > 0 && - (wt == proto.WireVarint || wt == proto.WireFixed32 || wt == proto.WireFixed64) { - // packed repeated field - var packedBuffer Buffer - for _, v := range sl { - if err := packedBuffer.encodeFieldValue(fd, v); err != nil { - return err - } - } - if err := cb.EncodeTagAndWireType(fd.GetNumber(), proto.WireBytes); err != nil { - return err - } - return cb.EncodeRawBytes(packedBuffer.Bytes()) - } else { - // non-packed repeated field - for _, v := range sl { - if err := cb.encodeFieldElement(fd, v); err != nil { - return err - } - } - return nil - } - } else { - return cb.encodeFieldElement(fd, val) - } -} - -func isPacked(fd *desc.FieldDescriptor) bool { - opts := fd.AsFieldDescriptorProto().GetOptions() - // if set, use that value - if opts != nil && opts.Packed != nil { - return opts.GetPacked() - } - // if unset: proto2 defaults to false, proto3 to true - return fd.GetFile().IsProto3() -} - -// sortable is used to sort map keys. Values will be integers (int32, int64, uint32, and uint64), -// bools, or strings. -type sortable []interface{} - -func (s sortable) Len() int { - return len(s) -} - -func (s sortable) Less(i, j int) bool { - vi := s[i] - vj := s[j] - switch reflect.TypeOf(vi).Kind() { - case reflect.Int32: - return vi.(int32) < vj.(int32) - case reflect.Int64: - return vi.(int64) < vj.(int64) - case reflect.Uint32: - return vi.(uint32) < vj.(uint32) - case reflect.Uint64: - return vi.(uint64) < vj.(uint64) - case reflect.String: - return vi.(string) < vj.(string) - case reflect.Bool: - return !vi.(bool) && vj.(bool) - default: - panic(fmt.Sprintf("cannot compare keys of type %v", reflect.TypeOf(vi))) - } -} - -func (s sortable) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -func (b *Buffer) encodeFieldElement(fd *desc.FieldDescriptor, val interface{}) error { - wt, err := getWireType(fd.GetType()) - if err != nil { - return err - } - if err := b.EncodeTagAndWireType(fd.GetNumber(), wt); err != nil { - return err - } - if err := b.encodeFieldValue(fd, val); err != nil { - return err - } - if wt == proto.WireStartGroup { - return b.EncodeTagAndWireType(fd.GetNumber(), proto.WireEndGroup) - } - return nil -} - -func (b *Buffer) encodeFieldValue(fd *desc.FieldDescriptor, val interface{}) error { - switch fd.GetType() { - case descriptorpb.FieldDescriptorProto_TYPE_BOOL: - v := val.(bool) - if v { - return b.EncodeVarint(1) - } - return b.EncodeVarint(0) - - case descriptorpb.FieldDescriptorProto_TYPE_ENUM, - descriptorpb.FieldDescriptorProto_TYPE_INT32: - v := val.(int32) - return b.EncodeVarint(uint64(v)) - - case descriptorpb.FieldDescriptorProto_TYPE_SFIXED32: - v := val.(int32) - return b.EncodeFixed32(uint64(v)) - - case descriptorpb.FieldDescriptorProto_TYPE_SINT32: - v := val.(int32) - return b.EncodeVarint(EncodeZigZag32(v)) - - case descriptorpb.FieldDescriptorProto_TYPE_UINT32: - v := val.(uint32) - return b.EncodeVarint(uint64(v)) - - case descriptorpb.FieldDescriptorProto_TYPE_FIXED32: - v := val.(uint32) - return b.EncodeFixed32(uint64(v)) - - case descriptorpb.FieldDescriptorProto_TYPE_INT64: - v := val.(int64) - return b.EncodeVarint(uint64(v)) - - case descriptorpb.FieldDescriptorProto_TYPE_SFIXED64: - v := val.(int64) - return b.EncodeFixed64(uint64(v)) - - case descriptorpb.FieldDescriptorProto_TYPE_SINT64: - v := val.(int64) - return b.EncodeVarint(EncodeZigZag64(v)) - - case descriptorpb.FieldDescriptorProto_TYPE_UINT64: - v := val.(uint64) - return b.EncodeVarint(v) - - case descriptorpb.FieldDescriptorProto_TYPE_FIXED64: - v := val.(uint64) - return b.EncodeFixed64(v) - - case descriptorpb.FieldDescriptorProto_TYPE_DOUBLE: - v := val.(float64) - return b.EncodeFixed64(math.Float64bits(v)) - - case descriptorpb.FieldDescriptorProto_TYPE_FLOAT: - v := val.(float32) - return b.EncodeFixed32(uint64(math.Float32bits(v))) - - case descriptorpb.FieldDescriptorProto_TYPE_BYTES: - v := val.([]byte) - return b.EncodeRawBytes(v) - - case descriptorpb.FieldDescriptorProto_TYPE_STRING: - v := val.(string) - return b.EncodeRawBytes(([]byte)(v)) - - case descriptorpb.FieldDescriptorProto_TYPE_MESSAGE: - return b.EncodeDelimitedMessage(val.(proto.Message)) - - case descriptorpb.FieldDescriptorProto_TYPE_GROUP: - // just append the nested message to this buffer - return b.EncodeMessage(val.(proto.Message)) - // whosoever writeth start-group tag (e.g. caller) is responsible for writing end-group tag - - default: - return fmt.Errorf("unrecognized field type: %v", fd.GetType()) - } -} - -func getWireType(t descriptorpb.FieldDescriptorProto_Type) (int8, error) { - switch t { - case descriptorpb.FieldDescriptorProto_TYPE_ENUM, - descriptorpb.FieldDescriptorProto_TYPE_BOOL, - descriptorpb.FieldDescriptorProto_TYPE_INT32, - descriptorpb.FieldDescriptorProto_TYPE_SINT32, - descriptorpb.FieldDescriptorProto_TYPE_UINT32, - descriptorpb.FieldDescriptorProto_TYPE_INT64, - descriptorpb.FieldDescriptorProto_TYPE_SINT64, - descriptorpb.FieldDescriptorProto_TYPE_UINT64: - return proto.WireVarint, nil - - case descriptorpb.FieldDescriptorProto_TYPE_FIXED32, - descriptorpb.FieldDescriptorProto_TYPE_SFIXED32, - descriptorpb.FieldDescriptorProto_TYPE_FLOAT: - return proto.WireFixed32, nil - - case descriptorpb.FieldDescriptorProto_TYPE_FIXED64, - descriptorpb.FieldDescriptorProto_TYPE_SFIXED64, - descriptorpb.FieldDescriptorProto_TYPE_DOUBLE: - return proto.WireFixed64, nil - - case descriptorpb.FieldDescriptorProto_TYPE_BYTES, - descriptorpb.FieldDescriptorProto_TYPE_STRING, - descriptorpb.FieldDescriptorProto_TYPE_MESSAGE: - return proto.WireBytes, nil - - case descriptorpb.FieldDescriptorProto_TYPE_GROUP: - return proto.WireStartGroup, nil - - default: - return 0, ErrBadWireType - } -} diff --git a/vendor/github.com/jhump/protoreflect/dynamic/binary.go b/vendor/github.com/jhump/protoreflect/dynamic/binary.go deleted file mode 100644 index 39e077a4..00000000 --- a/vendor/github.com/jhump/protoreflect/dynamic/binary.go +++ /dev/null @@ -1,193 +0,0 @@ -package dynamic - -// Binary serialization and de-serialization for dynamic messages - -import ( - "fmt" - "io" - - "github.com/golang/protobuf/proto" - - "github.com/jhump/protoreflect/codec" -) - -// defaultDeterminism, if true, will mean that calls to Marshal will produce -// deterministic output. This is used to make the output of proto.Marshal(...) -// deterministic (since there is no way to have that convey determinism intent). -// **This is only used from tests.** -var defaultDeterminism = false - -// Marshal serializes this message to bytes, returning an error if the operation -// fails. The resulting bytes are in the standard protocol buffer binary format. -func (m *Message) Marshal() ([]byte, error) { - var b codec.Buffer - b.SetDeterministic(defaultDeterminism) - if err := m.marshal(&b); err != nil { - return nil, err - } - return b.Bytes(), nil -} - -// MarshalAppend behaves exactly the same as Marshal, except instead of allocating a -// new byte slice to marshal into, it uses the provided byte slice. The backing array -// for the returned byte slice *may* be the same as the one that was passed in, but -// it's not guaranteed as a new backing array will automatically be allocated if -// more bytes need to be written than the provided buffer has capacity for. -func (m *Message) MarshalAppend(b []byte) ([]byte, error) { - codedBuf := codec.NewBuffer(b) - codedBuf.SetDeterministic(defaultDeterminism) - if err := m.marshal(codedBuf); err != nil { - return nil, err - } - return codedBuf.Bytes(), nil -} - -// MarshalDeterministic serializes this message to bytes in a deterministic way, -// returning an error if the operation fails. This differs from Marshal in that -// map keys will be sorted before serializing to bytes. The protobuf spec does -// not define ordering for map entries, so Marshal will use standard Go map -// iteration order (which will be random). But for cases where determinism is -// more important than performance, use this method instead. -func (m *Message) MarshalDeterministic() ([]byte, error) { - var b codec.Buffer - b.SetDeterministic(true) - if err := m.marshal(&b); err != nil { - return nil, err - } - return b.Bytes(), nil -} - -// MarshalAppendDeterministic behaves exactly the same as MarshalDeterministic, -// except instead of allocating a new byte slice to marshal into, it uses the -// provided byte slice. The backing array for the returned byte slice *may* be -// the same as the one that was passed in, but it's not guaranteed as a new -// backing array will automatically be allocated if more bytes need to be written -// than the provided buffer has capacity for. -func (m *Message) MarshalAppendDeterministic(b []byte) ([]byte, error) { - codedBuf := codec.NewBuffer(b) - codedBuf.SetDeterministic(true) - if err := m.marshal(codedBuf); err != nil { - return nil, err - } - return codedBuf.Bytes(), nil -} - -func (m *Message) marshal(b *codec.Buffer) error { - if m.GetMessageDescriptor().GetMessageOptions().GetMessageSetWireFormat() { - return fmt.Errorf("%s is a message set; marshaling message sets is not implemented", m.GetMessageDescriptor().GetFullyQualifiedName()) - } - if err := m.marshalKnownFields(b); err != nil { - return err - } - return m.marshalUnknownFields(b) -} - -func (m *Message) marshalKnownFields(b *codec.Buffer) error { - for _, tag := range m.knownFieldTags() { - itag := int32(tag) - val := m.values[itag] - fd := m.FindFieldDescriptor(itag) - if fd == nil { - panic(fmt.Sprintf("Couldn't find field for tag %d", itag)) - } - if err := b.EncodeFieldValue(fd, val); err != nil { - return err - } - } - return nil -} - -func (m *Message) marshalUnknownFields(b *codec.Buffer) error { - for _, tag := range m.unknownFieldTags() { - itag := int32(tag) - sl := m.unknownFields[itag] - for _, u := range sl { - if err := b.EncodeTagAndWireType(itag, u.Encoding); err != nil { - return err - } - switch u.Encoding { - case proto.WireBytes: - if err := b.EncodeRawBytes(u.Contents); err != nil { - return err - } - case proto.WireStartGroup: - _, _ = b.Write(u.Contents) - if err := b.EncodeTagAndWireType(itag, proto.WireEndGroup); err != nil { - return err - } - case proto.WireFixed32: - if err := b.EncodeFixed32(u.Value); err != nil { - return err - } - case proto.WireFixed64: - if err := b.EncodeFixed64(u.Value); err != nil { - return err - } - case proto.WireVarint: - if err := b.EncodeVarint(u.Value); err != nil { - return err - } - default: - return codec.ErrBadWireType - } - } - } - return nil -} - -// Unmarshal de-serializes the message that is present in the given bytes into -// this message. It first resets the current message. It returns an error if the -// given bytes do not contain a valid encoding of this message type. -func (m *Message) Unmarshal(b []byte) error { - m.Reset() - if err := m.UnmarshalMerge(b); err != nil { - return err - } - return m.Validate() -} - -// UnmarshalMerge de-serializes the message that is present in the given bytes -// into this message. Unlike Unmarshal, it does not first reset the message, -// instead merging the data in the given bytes into the existing data in this -// message. -func (m *Message) UnmarshalMerge(b []byte) error { - return m.unmarshal(codec.NewBuffer(b), false) -} - -func (m *Message) unmarshal(buf *codec.Buffer, isGroup bool) error { - if m.GetMessageDescriptor().GetMessageOptions().GetMessageSetWireFormat() { - return fmt.Errorf("%s is a message set; unmarshaling message sets is not implemented", m.GetMessageDescriptor().GetFullyQualifiedName()) - } - for !buf.EOF() { - fd, val, err := buf.DecodeFieldValue(m.FindFieldDescriptor, m.mf) - if err != nil { - if err == codec.ErrWireTypeEndGroup { - if isGroup { - // finished parsing group - return nil - } - return codec.ErrBadWireType - } - return err - } - - if fd == nil { - if m.unknownFields == nil { - m.unknownFields = map[int32][]UnknownField{} - } - uv := val.(codec.UnknownField) - u := UnknownField{ - Encoding: uv.Encoding, - Value: uv.Value, - Contents: uv.Contents, - } - m.unknownFields[uv.Tag] = append(m.unknownFields[uv.Tag], u) - } else if err := mergeField(m, fd, val); err != nil { - return err - } - } - if isGroup { - return io.ErrUnexpectedEOF - } - return nil -} diff --git a/vendor/github.com/jhump/protoreflect/dynamic/doc.go b/vendor/github.com/jhump/protoreflect/dynamic/doc.go deleted file mode 100644 index 5d7f45e4..00000000 --- a/vendor/github.com/jhump/protoreflect/dynamic/doc.go +++ /dev/null @@ -1,159 +0,0 @@ -// Package dynamic provides an implementation for a dynamic protobuf message. -// -// The dynamic message is essentially a message descriptor along with a map of -// tag numbers to values. It has a broad API for interacting with the message, -// including inspection and modification. Generally, most operations have two -// forms: a regular method that panics on bad input or error and a "Try" form -// of the method that will instead return an error. -// -// A dynamic message can optionally be constructed with a MessageFactory. The -// MessageFactory has various registries that may be used by the dynamic message, -// such as during de-serialization. The message factory is "inherited" by any -// other dynamic messages created, such as nested messages that are created -// during de-serialization. Similarly, any dynamic message created using -// MessageFactory.NewMessage will be associated with that factory, which in turn -// will be used to create other messages or parse extension fields during -// de-serialization. -// -// # Field Types -// -// The types of values expected by setters and returned by getters are the -// same as protoc generates for scalar fields. For repeated fields, there are -// methods for getting and setting values at a particular index or for adding -// an element. Similarly, for map fields, there are methods for getting and -// setting values for a particular key. -// -// If you use GetField for a repeated field, it will return a copy of all -// elements as a slice []interface{}. Similarly, using GetField for a map field -// will return a copy of all mappings as a map[interface{}]interface{}. You can -// also use SetField to supply an entire slice or map for repeated or map fields. -// The slice need not be []interface{} but can actually be typed according to -// the field's expected type. For example, a repeated uint64 field can be set -// using a slice of type []uint64. -// -// Descriptors for map fields describe them as repeated fields with a nested -// message type. The nested message type is a special generated type that -// represents a single mapping: key and value pair. The dynamic message has some -// special affordances for this representation. For example, you can use -// SetField to set a map field using a slice of these entry messages. Internally, -// the slice of entries will be converted to an actual map. Similarly, you can -// use AddRepeatedField with an entry message to add (or overwrite) a mapping. -// However, you cannot use GetRepeatedField or SetRepeatedField to modify maps, -// since those take numeric index arguments which are not relevant to maps -// (since maps in Go have no defined ordering). -// -// When setting field values in dynamic messages, the type-checking is lenient -// in that it accepts any named type with the right kind. So a string field can -// be assigned to any type that is defined as a string. Enum fields require -// int32 values (or any type that is defined as an int32). -// -// Unlike normal use of numeric values in Go, values will be automatically -// widened when assigned. So, for example, an int64 field can be set using an -// int32 value since it can be safely widened without truncation or loss of -// precision. Similar goes for uint32 values being converted to uint64 and -// float32 being converted to float64. Narrowing conversions are not done, -// however. Also, unsigned values will never be automatically converted to -// signed (and vice versa), and floating point values will never be -// automatically converted to integral values (and vice versa). Since the bit -// width of int and uint fields is allowed to be platform dependent, but will -// always be less than or equal to 64, they can only be used as values for -// int64 and uint64 fields, respectively. They cannot be used to set int32 or -// uint32 fields, which includes enums fields. -// -// Fields whose type is a nested message can have values set to either other -// dynamic messages or generated messages (e.g. pointers to structs generated by -// protoc). Getting a value for such a field will return the actual type it is -// set to (e.g. either a dynamic message or a generated message). If the value -// is not set and the message uses proto2 syntax, the default message returned -// will be whatever is returned by the dynamic message's MessageFactory (if the -// dynamic message was not created with a factory, it will use the logic of the -// zero value factory). In most typical cases, it will return a dynamic message, -// but if the factory is configured with a KnownTypeRegistry, or if the field's -// type is a well-known type, it will return a zero value generated message. -// -// # Unrecognized Fields -// -// Unrecognized fields are preserved by the dynamic message when unmarshaling -// from the standard binary format. If the message's MessageFactory was -// configured with an ExtensionRegistry, it will be used to identify and parse -// extension fields for the message. -// -// Unrecognized fields can dynamically become recognized fields if the -// application attempts to retrieve an unrecognized field's value using a -// FieldDescriptor. In this case, the given FieldDescriptor is used to parse the -// unknown field and move the parsed value into the message's set of known -// fields. This behavior is most suited to the use of extensions, where an -// ExtensionRegistry is not setup with all known extensions ahead of time. But -// it can even happen for non-extension fields! Here's an example scenario where -// a non-extension field can initially be unknown and become known: -// -// 1. A dynamic message is created with a descriptor, A, and then -// de-serialized from a stream of bytes. The stream includes an -// unrecognized tag T. The message will include tag T in its unrecognized -// field set. -// 2. Another call site retrieves a newer descriptor, A', which includes a -// newly added field with tag T. -// 3. That other call site then uses a FieldDescriptor to access the value of -// the new field. This will cause the dynamic message to parse the bytes -// for the unknown tag T and store them as a known field. -// 4. Subsequent operations for tag T, including setting the field using only -// tag number or de-serializing a stream that includes tag T, will operate -// as if that tag were part of the original descriptor, A. -// -// # Compatibility -// -// In addition to implementing the proto.Message interface, the included -// Message type also provides an XXX_MessageName() method, so it can work with -// proto.MessageName. And it provides a Descriptor() method that behaves just -// like the method of the same signature in messages generated by protoc. -// Because of this, it is actually compatible with proto.Message in many (though -// not all) contexts. In particular, it is compatible with proto.Marshal and -// proto.Unmarshal for serializing and de-serializing messages. -// -// The dynamic message supports binary and text marshaling, using protobuf's -// well-defined binary format and the same text format that protoc-generated -// types use. It also supports JSON serialization/de-serialization by -// implementing the json.Marshaler and json.Unmarshaler interfaces. And dynamic -// messages can safely be used with the jsonpb package for JSON serialization -// and de-serialization. -// -// In addition to implementing the proto.Message interface and numerous related -// methods, it also provides inter-op with generated messages via conversion. -// The ConvertTo, ConvertFrom, MergeInto, and MergeFrom methods copy message -// contents from a dynamic message to a generated message and vice versa. -// -// When copying from a generated message into a dynamic message, if the -// generated message contains fields unknown to the dynamic message (e.g. not -// present in the descriptor used to create the dynamic message), these fields -// become known to the dynamic message (as per behavior described above in -// "Unrecognized Fields"). If the generated message has unrecognized fields of -// its own, including unrecognized extensions, they are preserved in the dynamic -// message. It is possible that the dynamic message knows about fields that the -// generated message did not, like if it has a different version of the -// descriptor or its MessageFactory has an ExtensionRegistry that knows about -// different extensions than were linked into the program. In this case, these -// unrecognized fields in the generated message will be known fields in the -// dynamic message. -// -// Similarly, when copying from a dynamic message into a generated message, if -// the dynamic message has unrecognized fields they can be preserved in the -// generated message (currently only for syntax proto2 since proto3 generated -// messages do not preserve unrecognized fields). If the generated message knows -// about fields that the dynamic message does not, these unrecognized fields may -// become known fields in the generated message. -// -// # Registries -// -// This package also contains a couple of registries, for managing known types -// and descriptors. -// -// The KnownTypeRegistry allows de-serialization of a dynamic message to use -// generated message types, instead of dynamic messages, for some kinds of -// nested message fields. This is particularly useful for working with proto -// messages that have special encodings as JSON (e.g. the well-known types), -// since the dynamic message does not try to handle these special cases in its -// JSON marshaling facilities. -// -// The ExtensionRegistry allows for recognizing and parsing extensions fields -// (for proto2 messages). -package dynamic diff --git a/vendor/github.com/jhump/protoreflect/dynamic/dynamic_message.go b/vendor/github.com/jhump/protoreflect/dynamic/dynamic_message.go deleted file mode 100644 index ff136b0e..00000000 --- a/vendor/github.com/jhump/protoreflect/dynamic/dynamic_message.go +++ /dev/null @@ -1,2830 +0,0 @@ -package dynamic - -import ( - "bytes" - "compress/gzip" - "errors" - "fmt" - "reflect" - "sort" - "strings" - - "github.com/golang/protobuf/proto" - protov2 "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/types/descriptorpb" - - "github.com/jhump/protoreflect/codec" - "github.com/jhump/protoreflect/desc" - "github.com/jhump/protoreflect/internal" -) - -// ErrUnknownTagNumber is an error that is returned when an operation refers -// to an unknown tag number. -var ErrUnknownTagNumber = errors.New("unknown tag number") - -// UnknownTagNumberError is the same as ErrUnknownTagNumber. -// Deprecated: use ErrUnknownTagNumber -var UnknownTagNumberError = ErrUnknownTagNumber - -// ErrUnknownFieldName is an error that is returned when an operation refers -// to an unknown field name. -var ErrUnknownFieldName = errors.New("unknown field name") - -// UnknownFieldNameError is the same as ErrUnknownFieldName. -// Deprecated: use ErrUnknownFieldName -var UnknownFieldNameError = ErrUnknownFieldName - -// ErrFieldIsNotMap is an error that is returned when map-related operations -// are attempted with fields that are not maps. -var ErrFieldIsNotMap = errors.New("field is not a map type") - -// FieldIsNotMapError is the same as ErrFieldIsNotMap. -// Deprecated: use ErrFieldIsNotMap -var FieldIsNotMapError = ErrFieldIsNotMap - -// ErrFieldIsNotRepeated is an error that is returned when repeated field -// operations are attempted with fields that are not repeated. -var ErrFieldIsNotRepeated = errors.New("field is not repeated") - -// FieldIsNotRepeatedError is the same as ErrFieldIsNotRepeated. -// Deprecated: use ErrFieldIsNotRepeated -var FieldIsNotRepeatedError = ErrFieldIsNotRepeated - -// ErrIndexOutOfRange is an error that is returned when an invalid index is -// provided when access a single element of a repeated field. -var ErrIndexOutOfRange = errors.New("index is out of range") - -// IndexOutOfRangeError is the same as ErrIndexOutOfRange. -// Deprecated: use ErrIndexOutOfRange -var IndexOutOfRangeError = ErrIndexOutOfRange - -// ErrNumericOverflow is an error returned by operations that encounter a -// numeric value that is too large, for example de-serializing a value into an -// int32 field when the value is larger that can fit into a 32-bit value. -var ErrNumericOverflow = errors.New("numeric value is out of range") - -// NumericOverflowError is the same as ErrNumericOverflow. -// Deprecated: use ErrNumericOverflow -var NumericOverflowError = ErrNumericOverflow - -var typeOfProtoMessage = reflect.TypeOf((*proto.Message)(nil)).Elem() -var typeOfDynamicMessage = reflect.TypeOf((*Message)(nil)) -var typeOfBytes = reflect.TypeOf(([]byte)(nil)) - -// Message is a dynamic protobuf message. Instead of a generated struct, -// like most protobuf messages, this is a map of field number to values and -// a message descriptor, which is used to validate the field values and -// also to de-serialize messages (from the standard binary format, as well -// as from the text format and from JSON). -type Message struct { - md *desc.MessageDescriptor - er *ExtensionRegistry - mf *MessageFactory - extraFields map[int32]*desc.FieldDescriptor - values map[int32]interface{} - unknownFields map[int32][]UnknownField -} - -// UnknownField represents a field that was parsed from the binary wire -// format for a message, but was not a recognized field number. Enough -// information is preserved so that re-serializing the message won't lose -// any of the unrecognized data. -type UnknownField struct { - // Encoding indicates how the unknown field was encoded on the wire. If it - // is proto.WireBytes or proto.WireGroupStart then Contents will be set to - // the raw bytes. If it is proto.WireTypeFixed32 then the data is in the least - // significant 32 bits of Value. Otherwise, the data is in all 64 bits of - // Value. - Encoding int8 - Contents []byte - Value uint64 -} - -// NewMessage creates a new dynamic message for the type represented by the given -// message descriptor. During de-serialization, a default MessageFactory is used to -// instantiate any nested message fields and no extension fields will be parsed. To -// use a custom MessageFactory or ExtensionRegistry, use MessageFactory.NewMessage. -func NewMessage(md *desc.MessageDescriptor) *Message { - return NewMessageWithMessageFactory(md, nil) -} - -// NewMessageWithExtensionRegistry creates a new dynamic message for the type -// represented by the given message descriptor. During de-serialization, the given -// ExtensionRegistry is used to parse extension fields and nested messages will be -// instantiated using dynamic.NewMessageFactoryWithExtensionRegistry(er). -func NewMessageWithExtensionRegistry(md *desc.MessageDescriptor, er *ExtensionRegistry) *Message { - mf := NewMessageFactoryWithExtensionRegistry(er) - return NewMessageWithMessageFactory(md, mf) -} - -// NewMessageWithMessageFactory creates a new dynamic message for the type -// represented by the given message descriptor. During de-serialization, the given -// MessageFactory is used to instantiate nested messages. -func NewMessageWithMessageFactory(md *desc.MessageDescriptor, mf *MessageFactory) *Message { - var er *ExtensionRegistry - if mf != nil { - er = mf.er - } - return &Message{ - md: md, - mf: mf, - er: er, - } -} - -// AsDynamicMessage converts the given message to a dynamic message. If the -// given message is dynamic, it is returned. Otherwise, a dynamic message is -// created using NewMessage. -func AsDynamicMessage(msg proto.Message) (*Message, error) { - return AsDynamicMessageWithMessageFactory(msg, nil) -} - -// AsDynamicMessageWithExtensionRegistry converts the given message to a dynamic -// message. If the given message is dynamic, it is returned. Otherwise, a -// dynamic message is created using NewMessageWithExtensionRegistry. -func AsDynamicMessageWithExtensionRegistry(msg proto.Message, er *ExtensionRegistry) (*Message, error) { - mf := NewMessageFactoryWithExtensionRegistry(er) - return AsDynamicMessageWithMessageFactory(msg, mf) -} - -// AsDynamicMessageWithMessageFactory converts the given message to a dynamic -// message. If the given message is dynamic, it is returned. Otherwise, a -// dynamic message is created using NewMessageWithMessageFactory. -func AsDynamicMessageWithMessageFactory(msg proto.Message, mf *MessageFactory) (*Message, error) { - if dm, ok := msg.(*Message); ok { - return dm, nil - } - md, err := desc.LoadMessageDescriptorForMessage(msg) - if err != nil { - return nil, err - } - dm := NewMessageWithMessageFactory(md, mf) - err = dm.mergeFrom(msg) - if err != nil { - return nil, err - } - return dm, nil -} - -// GetMessageDescriptor returns a descriptor for this message's type. -func (m *Message) GetMessageDescriptor() *desc.MessageDescriptor { - return m.md -} - -// GetKnownFields returns a slice of descriptors for all known fields. The -// fields will not be in any defined order. -func (m *Message) GetKnownFields() []*desc.FieldDescriptor { - if len(m.extraFields) == 0 { - return m.md.GetFields() - } - flds := make([]*desc.FieldDescriptor, len(m.md.GetFields()), len(m.md.GetFields())+len(m.extraFields)) - copy(flds, m.md.GetFields()) - for _, fld := range m.extraFields { - if !fld.IsExtension() { - flds = append(flds, fld) - } - } - return flds -} - -// GetKnownExtensions returns a slice of descriptors for all extensions known by -// the message's extension registry. The fields will not be in any defined order. -func (m *Message) GetKnownExtensions() []*desc.FieldDescriptor { - if !m.md.IsExtendable() { - return nil - } - exts := m.er.AllExtensionsForType(m.md.GetFullyQualifiedName()) - for _, fld := range m.extraFields { - if fld.IsExtension() { - exts = append(exts, fld) - } - } - return exts -} - -// GetUnknownFields returns a slice of tag numbers for all unknown fields that -// this message contains. The tags will not be in any defined order. -func (m *Message) GetUnknownFields() []int32 { - flds := make([]int32, 0, len(m.unknownFields)) - for tag := range m.unknownFields { - flds = append(flds, tag) - } - return flds -} - -// Descriptor returns the serialized form of the file descriptor in which the -// message was defined and a path to the message type therein. This mimics the -// method of the same name on message types generated by protoc. -func (m *Message) Descriptor() ([]byte, []int) { - // get encoded file descriptor - b, err := proto.Marshal(m.md.GetFile().AsProto()) - if err != nil { - panic(fmt.Sprintf("failed to get encoded descriptor for %s: %v", m.md.GetFile().GetName(), err)) - } - var zippedBytes bytes.Buffer - w := gzip.NewWriter(&zippedBytes) - if _, err := w.Write(b); err != nil { - panic(fmt.Sprintf("failed to get encoded descriptor for %s: %v", m.md.GetFile().GetName(), err)) - } - if err := w.Close(); err != nil { - panic(fmt.Sprintf("failed to get an encoded descriptor for %s: %v", m.md.GetFile().GetName(), err)) - } - - // and path to message - path := []int{} - var d desc.Descriptor - name := m.md.GetFullyQualifiedName() - for d = m.md.GetParent(); d != nil; name, d = d.GetFullyQualifiedName(), d.GetParent() { - found := false - switch d := d.(type) { - case (*desc.FileDescriptor): - for i, md := range d.GetMessageTypes() { - if md.GetFullyQualifiedName() == name { - found = true - path = append(path, i) - } - } - case (*desc.MessageDescriptor): - for i, md := range d.GetNestedMessageTypes() { - if md.GetFullyQualifiedName() == name { - found = true - path = append(path, i) - } - } - } - if !found { - panic(fmt.Sprintf("failed to compute descriptor path for %s", m.md.GetFullyQualifiedName())) - } - } - // reverse the path - i := 0 - j := len(path) - 1 - for i < j { - path[i], path[j] = path[j], path[i] - i++ - j-- - } - - return zippedBytes.Bytes(), path -} - -// XXX_MessageName returns the fully qualified name of this message's type. This -// allows dynamic messages to be used with proto.MessageName. -func (m *Message) XXX_MessageName() string { - return m.md.GetFullyQualifiedName() -} - -// FindFieldDescriptor returns a field descriptor for the given tag number. This -// searches known fields in the descriptor, known fields discovered during calls -// to GetField or SetField, and extension fields known by the message's extension -// registry. It returns nil if the tag is unknown. -func (m *Message) FindFieldDescriptor(tagNumber int32) *desc.FieldDescriptor { - fd := m.md.FindFieldByNumber(tagNumber) - if fd != nil { - return fd - } - fd = m.er.FindExtension(m.md.GetFullyQualifiedName(), tagNumber) - if fd != nil { - return fd - } - return m.extraFields[tagNumber] -} - -// FindFieldDescriptorByName returns a field descriptor for the given field -// name. This searches known fields in the descriptor, known fields discovered -// during calls to GetField or SetField, and extension fields known by the -// message's extension registry. It returns nil if the name is unknown. If the -// given name refers to an extension, it should be fully qualified and may be -// optionally enclosed in parentheses or brackets. -func (m *Message) FindFieldDescriptorByName(name string) *desc.FieldDescriptor { - if name == "" { - return nil - } - fd := m.md.FindFieldByName(name) - if fd != nil { - return fd - } - mustBeExt := false - if name[0] == '(' { - if name[len(name)-1] != ')' { - // malformed name - return nil - } - mustBeExt = true - name = name[1 : len(name)-1] - } else if name[0] == '[' { - if name[len(name)-1] != ']' { - // malformed name - return nil - } - mustBeExt = true - name = name[1 : len(name)-1] - } - fd = m.er.FindExtensionByName(m.md.GetFullyQualifiedName(), name) - if fd != nil { - return fd - } - for _, fd := range m.extraFields { - if fd.IsExtension() && name == fd.GetFullyQualifiedName() { - return fd - } else if !mustBeExt && !fd.IsExtension() && name == fd.GetName() { - return fd - } - } - - return nil -} - -// FindFieldDescriptorByJSONName returns a field descriptor for the given JSON -// name. This searches known fields in the descriptor, known fields discovered -// during calls to GetField or SetField, and extension fields known by the -// message's extension registry. If no field matches the given JSON name, it -// will fall back to searching field names (e.g. FindFieldDescriptorByName). If -// this also yields no match, nil is returned. -func (m *Message) FindFieldDescriptorByJSONName(name string) *desc.FieldDescriptor { - if name == "" { - return nil - } - fd := m.md.FindFieldByJSONName(name) - if fd != nil { - return fd - } - mustBeExt := false - if name[0] == '(' { - if name[len(name)-1] != ')' { - // malformed name - return nil - } - mustBeExt = true - name = name[1 : len(name)-1] - } else if name[0] == '[' { - if name[len(name)-1] != ']' { - // malformed name - return nil - } - mustBeExt = true - name = name[1 : len(name)-1] - } - fd = m.er.FindExtensionByJSONName(m.md.GetFullyQualifiedName(), name) - if fd != nil { - return fd - } - for _, fd := range m.extraFields { - if fd.IsExtension() && name == fd.GetFullyQualifiedJSONName() { - return fd - } else if !mustBeExt && !fd.IsExtension() && name == fd.GetJSONName() { - return fd - } - } - - // try non-JSON names - return m.FindFieldDescriptorByName(name) -} - -func (m *Message) checkField(fd *desc.FieldDescriptor) error { - return checkField(fd, m.md) -} - -func checkField(fd *desc.FieldDescriptor, md *desc.MessageDescriptor) error { - if fd.GetOwner().GetFullyQualifiedName() != md.GetFullyQualifiedName() { - return fmt.Errorf("given field, %s, is for wrong message type: %s; expecting %s", fd.GetName(), fd.GetOwner().GetFullyQualifiedName(), md.GetFullyQualifiedName()) - } - if fd.IsExtension() && !md.IsExtension(fd.GetNumber()) { - return fmt.Errorf("given field, %s, is an extension but is not in message extension range: %v", fd.GetFullyQualifiedName(), md.GetExtensionRanges()) - } - return nil -} - -// GetField returns the value for the given field descriptor. It panics if an -// error is encountered. See TryGetField. -func (m *Message) GetField(fd *desc.FieldDescriptor) interface{} { - if v, err := m.TryGetField(fd); err != nil { - panic(err.Error()) - } else { - return v - } -} - -// TryGetField returns the value for the given field descriptor. An error is -// returned if the given field descriptor does not belong to the right message -// type. -// -// The Go type of the returned value, for scalar fields, is the same as protoc -// would generate for the field (in a non-dynamic message). The table below -// lists the scalar types and the corresponding Go types. -// -// +-------------------------+-----------+ -// | Declared Type | Go Type | -// +-------------------------+-----------+ -// | int32, sint32, sfixed32 | int32 | -// | int64, sint64, sfixed64 | int64 | -// | uint32, fixed32 | uint32 | -// | uint64, fixed64 | uint64 | -// | float | float32 | -// | double | double32 | -// | bool | bool | -// | string | string | -// | bytes | []byte | -// +-------------------------+-----------+ -// -// Values for enum fields will always be int32 values. You can use the enum -// descriptor associated with the field to lookup value names with those values. -// Values for message type fields may be an instance of the generated type *or* -// may be another *dynamic.Message that represents the type. -// -// If the given field is a map field, the returned type will be -// map[interface{}]interface{}. The actual concrete types of keys and values is -// as described above. If the given field is a (non-map) repeated field, the -// returned type is always []interface{}; the type of the actual elements is as -// described above. -// -// If this message has no value for the given field, its default value is -// returned. If the message is defined in a file with "proto3" syntax, the -// default is always the zero value for the field. The default value for map and -// repeated fields is a nil map or slice (respectively). For field's whose types -// is a message, the default value is an empty message for "proto2" syntax or a -// nil message for "proto3" syntax. Note that the in the latter case, a non-nil -// interface with a nil pointer is returned, not a nil interface. Also note that -// whether the returned value is an empty message or nil depends on if *this* -// message was defined as "proto3" syntax, not the message type referred to by -// the field's type. -// -// If the given field descriptor is not known (e.g. not present in the message -// descriptor) but corresponds to an unknown field, the unknown value will be -// parsed and become known. The parsed value will be returned, or an error will -// be returned if the unknown value cannot be parsed according to the field -// descriptor's type information. -func (m *Message) TryGetField(fd *desc.FieldDescriptor) (interface{}, error) { - if err := m.checkField(fd); err != nil { - return nil, err - } - return m.getField(fd) -} - -// GetFieldByName returns the value for the field with the given name. It panics -// if an error is encountered. See TryGetFieldByName. -func (m *Message) GetFieldByName(name string) interface{} { - if v, err := m.TryGetFieldByName(name); err != nil { - panic(err.Error()) - } else { - return v - } -} - -// TryGetFieldByName returns the value for the field with the given name. An -// error is returned if the given name is unknown. If the given name refers to -// an extension field, it should be fully qualified and optionally enclosed in -// parenthesis or brackets. -// -// If this message has no value for the given field, its default value is -// returned. (See TryGetField for more info on types and default field values.) -func (m *Message) TryGetFieldByName(name string) (interface{}, error) { - fd := m.FindFieldDescriptorByName(name) - if fd == nil { - return nil, UnknownFieldNameError - } - return m.getField(fd) -} - -// GetFieldByNumber returns the value for the field with the given tag number. -// It panics if an error is encountered. See TryGetFieldByNumber. -func (m *Message) GetFieldByNumber(tagNumber int) interface{} { - if v, err := m.TryGetFieldByNumber(tagNumber); err != nil { - panic(err.Error()) - } else { - return v - } -} - -// TryGetFieldByNumber returns the value for the field with the given tag -// number. An error is returned if the given tag is unknown. -// -// If this message has no value for the given field, its default value is -// returned. (See TryGetField for more info on types and default field values.) -func (m *Message) TryGetFieldByNumber(tagNumber int) (interface{}, error) { - fd := m.FindFieldDescriptor(int32(tagNumber)) - if fd == nil { - return nil, UnknownTagNumberError - } - return m.getField(fd) -} - -func (m *Message) getField(fd *desc.FieldDescriptor) (interface{}, error) { - return m.doGetField(fd, false) -} - -func (m *Message) doGetField(fd *desc.FieldDescriptor, nilIfAbsent bool) (interface{}, error) { - res := m.values[fd.GetNumber()] - if res == nil { - var err error - if res, err = m.parseUnknownField(fd); err != nil { - return nil, err - } - if res == nil { - if nilIfAbsent { - return nil, nil - } else { - def := fd.GetDefaultValue() - if def != nil { - return def, nil - } - // GetDefaultValue only returns nil for message types - md := fd.GetMessageType() - if m.md.IsProto3() { - return nilMessage(md), nil - } else { - // for proto2, return default instance of message - return m.mf.NewMessage(md), nil - } - } - } - } - rt := reflect.TypeOf(res) - if rt.Kind() == reflect.Map { - // make defensive copies to prevent caller from storing illegal keys and values - m := res.(map[interface{}]interface{}) - res := map[interface{}]interface{}{} - for k, v := range m { - res[k] = v - } - return res, nil - } else if rt.Kind() == reflect.Slice && rt != typeOfBytes { - // make defensive copies to prevent caller from storing illegal elements - sl := res.([]interface{}) - res := make([]interface{}, len(sl)) - copy(res, sl) - return res, nil - } - return res, nil -} - -func nilMessage(md *desc.MessageDescriptor) interface{} { - // try to return a proper nil pointer - msgType := proto.MessageType(md.GetFullyQualifiedName()) - if msgType != nil && msgType.Implements(typeOfProtoMessage) { - return reflect.Zero(msgType).Interface().(proto.Message) - } - // fallback to nil dynamic message pointer - return (*Message)(nil) -} - -// HasField returns true if this message has a value for the given field. If the -// given field is not valid (e.g. belongs to a different message type), false is -// returned. If this message is defined in a file with "proto3" syntax, this -// will return false even if a field was explicitly assigned its zero value (the -// zero values for a field are intentionally indistinguishable from absent). -func (m *Message) HasField(fd *desc.FieldDescriptor) bool { - if err := m.checkField(fd); err != nil { - return false - } - return m.HasFieldNumber(int(fd.GetNumber())) -} - -// HasFieldName returns true if this message has a value for a field with the -// given name. If the given name is unknown, this returns false. -func (m *Message) HasFieldName(name string) bool { - fd := m.FindFieldDescriptorByName(name) - if fd == nil { - return false - } - return m.HasFieldNumber(int(fd.GetNumber())) -} - -// HasFieldNumber returns true if this message has a value for a field with the -// given tag number. If the given tag is unknown, this returns false. -func (m *Message) HasFieldNumber(tagNumber int) bool { - if _, ok := m.values[int32(tagNumber)]; ok { - return true - } - _, ok := m.unknownFields[int32(tagNumber)] - return ok -} - -// SetField sets the value for the given field descriptor to the given value. It -// panics if an error is encountered. See TrySetField. -func (m *Message) SetField(fd *desc.FieldDescriptor, val interface{}) { - if err := m.TrySetField(fd, val); err != nil { - panic(err.Error()) - } -} - -// TrySetField sets the value for the given field descriptor to the given value. -// An error is returned if the given field descriptor does not belong to the -// right message type or if the given value is not a correct/compatible type for -// the given field. -// -// The Go type expected for a field is the same as TryGetField would return for -// the field. So message values can be supplied as either the correct generated -// message type or as a *dynamic.Message. -// -// Since it is cumbersome to work with dynamic messages, some concessions are -// made to simplify usage regarding types: -// -// 1. If a numeric type is provided that can be converted *without loss or -// overflow*, it is accepted. This allows for setting int64 fields using int -// or int32 values. Similarly for uint64 with uint and uint32 values and for -// float64 fields with float32 values. -// 2. The value can be a named type, as long as its underlying type is correct. -// 3. Map and repeated fields can be set using any kind of concrete map or -// slice type, as long as the values within are all of the correct type. So -// a field defined as a 'map` can be set using a -// map[string]int32, a map[string]interface{}, or even a -// map[interface{}]interface{}. -// 4. Finally, dynamic code that chooses to not treat maps as a special-case -// find that they can set map fields using a slice where each element is a -// message that matches the implicit map-entry field message type. -// -// If the given field descriptor is not known (e.g. not present in the message -// descriptor) it will become known. Subsequent operations using tag numbers or -// names will be able to resolve the newly-known type. If the message has a -// value for the unknown value, it is cleared, replaced by the given known -// value. -func (m *Message) TrySetField(fd *desc.FieldDescriptor, val interface{}) error { - if err := m.checkField(fd); err != nil { - return err - } - return m.setField(fd, val) -} - -// SetFieldByName sets the value for the field with the given name to the given -// value. It panics if an error is encountered. See TrySetFieldByName. -func (m *Message) SetFieldByName(name string, val interface{}) { - if err := m.TrySetFieldByName(name, val); err != nil { - panic(err.Error()) - } -} - -// TrySetFieldByName sets the value for the field with the given name to the -// given value. An error is returned if the given name is unknown or if the -// given value has an incorrect type. If the given name refers to an extension -// field, it should be fully qualified and optionally enclosed in parenthesis or -// brackets. -// -// (See TrySetField for more info on types.) -func (m *Message) TrySetFieldByName(name string, val interface{}) error { - fd := m.FindFieldDescriptorByName(name) - if fd == nil { - return UnknownFieldNameError - } - return m.setField(fd, val) -} - -// SetFieldByNumber sets the value for the field with the given tag number to -// the given value. It panics if an error is encountered. See -// TrySetFieldByNumber. -func (m *Message) SetFieldByNumber(tagNumber int, val interface{}) { - if err := m.TrySetFieldByNumber(tagNumber, val); err != nil { - panic(err.Error()) - } -} - -// TrySetFieldByNumber sets the value for the field with the given tag number to -// the given value. An error is returned if the given tag is unknown or if the -// given value has an incorrect type. -// -// (See TrySetField for more info on types.) -func (m *Message) TrySetFieldByNumber(tagNumber int, val interface{}) error { - fd := m.FindFieldDescriptor(int32(tagNumber)) - if fd == nil { - return UnknownTagNumberError - } - return m.setField(fd, val) -} - -func (m *Message) setField(fd *desc.FieldDescriptor, val interface{}) error { - var err error - if val, err = validFieldValue(fd, val); err != nil { - return err - } - m.internalSetField(fd, val) - return nil -} - -func (m *Message) internalSetField(fd *desc.FieldDescriptor, val interface{}) { - if fd.IsRepeated() { - // Unset fields and zero-length fields are indistinguishable, in both - // proto2 and proto3 syntax - if reflect.ValueOf(val).Len() == 0 { - if m.values != nil { - delete(m.values, fd.GetNumber()) - } - return - } - } else if m.md.IsProto3() && fd.GetOneOf() == nil { - // proto3 considers fields that are set to their zero value as unset - // (we already handled repeated fields above) - var equal bool - if b, ok := val.([]byte); ok { - // can't compare slices, so we have to special-case []byte values - equal = ok && bytes.Equal(b, fd.GetDefaultValue().([]byte)) - } else { - defVal := fd.GetDefaultValue() - equal = defVal == val - if !equal && defVal == nil { - // above just checks if value is the nil interface, - // but we should also test if the given value is a - // nil pointer - rv := reflect.ValueOf(val) - if rv.Kind() == reflect.Ptr && rv.IsNil() { - equal = true - } - } - } - if equal { - if m.values != nil { - delete(m.values, fd.GetNumber()) - } - return - } - } - if m.values == nil { - m.values = map[int32]interface{}{} - } - m.values[fd.GetNumber()] = val - // if this field is part of a one-of, make sure all other one-of choices are cleared - od := fd.GetOneOf() - if od != nil { - for _, other := range od.GetChoices() { - if other.GetNumber() != fd.GetNumber() { - delete(m.values, other.GetNumber()) - } - } - } - // also clear any unknown fields - if m.unknownFields != nil { - delete(m.unknownFields, fd.GetNumber()) - } - // and add this field if it was previously unknown - if existing := m.FindFieldDescriptor(fd.GetNumber()); existing == nil { - m.addField(fd) - } -} - -func (m *Message) addField(fd *desc.FieldDescriptor) { - if m.extraFields == nil { - m.extraFields = map[int32]*desc.FieldDescriptor{} - } - m.extraFields[fd.GetNumber()] = fd -} - -// ClearField removes any value for the given field. It panics if an error is -// encountered. See TryClearField. -func (m *Message) ClearField(fd *desc.FieldDescriptor) { - if err := m.TryClearField(fd); err != nil { - panic(err.Error()) - } -} - -// TryClearField removes any value for the given field. An error is returned if -// the given field descriptor does not belong to the right message type. -func (m *Message) TryClearField(fd *desc.FieldDescriptor) error { - if err := m.checkField(fd); err != nil { - return err - } - m.clearField(fd) - return nil -} - -// ClearFieldByName removes any value for the field with the given name. It -// panics if an error is encountered. See TryClearFieldByName. -func (m *Message) ClearFieldByName(name string) { - if err := m.TryClearFieldByName(name); err != nil { - panic(err.Error()) - } -} - -// TryClearFieldByName removes any value for the field with the given name. An -// error is returned if the given name is unknown. If the given name refers to -// an extension field, it should be fully qualified and optionally enclosed in -// parenthesis or brackets. -func (m *Message) TryClearFieldByName(name string) error { - fd := m.FindFieldDescriptorByName(name) - if fd == nil { - return UnknownFieldNameError - } - m.clearField(fd) - return nil -} - -// ClearFieldByNumber removes any value for the field with the given tag number. -// It panics if an error is encountered. See TryClearFieldByNumber. -func (m *Message) ClearFieldByNumber(tagNumber int) { - if err := m.TryClearFieldByNumber(tagNumber); err != nil { - panic(err.Error()) - } -} - -// TryClearFieldByNumber removes any value for the field with the given tag -// number. An error is returned if the given tag is unknown. -func (m *Message) TryClearFieldByNumber(tagNumber int) error { - fd := m.FindFieldDescriptor(int32(tagNumber)) - if fd == nil { - return UnknownTagNumberError - } - m.clearField(fd) - return nil -} - -func (m *Message) clearField(fd *desc.FieldDescriptor) { - // clear value - if m.values != nil { - delete(m.values, fd.GetNumber()) - } - // also clear any unknown fields - if m.unknownFields != nil { - delete(m.unknownFields, fd.GetNumber()) - } - // and add this field if it was previously unknown - if existing := m.FindFieldDescriptor(fd.GetNumber()); existing == nil { - m.addField(fd) - } -} - -// GetOneOfField returns which of the given one-of's fields is set and the -// corresponding value. It panics if an error is encountered. See -// TryGetOneOfField. -func (m *Message) GetOneOfField(od *desc.OneOfDescriptor) (*desc.FieldDescriptor, interface{}) { - if fd, val, err := m.TryGetOneOfField(od); err != nil { - panic(err.Error()) - } else { - return fd, val - } -} - -// TryGetOneOfField returns which of the given one-of's fields is set and the -// corresponding value. An error is returned if the given one-of belongs to the -// wrong message type. If the given one-of has no field set, this method will -// return nil, nil. -// -// The type of the value, if one is set, is the same as would be returned by -// TryGetField using the returned field descriptor. -// -// Like with TryGetField, if the given one-of contains any fields that are not -// known (e.g. not present in this message's descriptor), they will become known -// and any unknown value will be parsed (and become a known value on success). -func (m *Message) TryGetOneOfField(od *desc.OneOfDescriptor) (*desc.FieldDescriptor, interface{}, error) { - if od.GetOwner().GetFullyQualifiedName() != m.md.GetFullyQualifiedName() { - return nil, nil, fmt.Errorf("given one-of, %s, is for wrong message type: %s; expecting %s", od.GetName(), od.GetOwner().GetFullyQualifiedName(), m.md.GetFullyQualifiedName()) - } - for _, fd := range od.GetChoices() { - val, err := m.doGetField(fd, true) - if err != nil { - return nil, nil, err - } - if val != nil { - return fd, val, nil - } - } - return nil, nil, nil -} - -// ClearOneOfField removes any value for any of the given one-of's fields. It -// panics if an error is encountered. See TryClearOneOfField. -func (m *Message) ClearOneOfField(od *desc.OneOfDescriptor) { - if err := m.TryClearOneOfField(od); err != nil { - panic(err.Error()) - } -} - -// TryClearOneOfField removes any value for any of the given one-of's fields. An -// error is returned if the given one-of descriptor does not belong to the right -// message type. -func (m *Message) TryClearOneOfField(od *desc.OneOfDescriptor) error { - if od.GetOwner().GetFullyQualifiedName() != m.md.GetFullyQualifiedName() { - return fmt.Errorf("given one-of, %s, is for wrong message type: %s; expecting %s", od.GetName(), od.GetOwner().GetFullyQualifiedName(), m.md.GetFullyQualifiedName()) - } - for _, fd := range od.GetChoices() { - m.clearField(fd) - } - return nil -} - -// GetMapField returns the value for the given map field descriptor and given -// key. It panics if an error is encountered. See TryGetMapField. -func (m *Message) GetMapField(fd *desc.FieldDescriptor, key interface{}) interface{} { - if v, err := m.TryGetMapField(fd, key); err != nil { - panic(err.Error()) - } else { - return v - } -} - -// TryGetMapField returns the value for the given map field descriptor and given -// key. An error is returned if the given field descriptor does not belong to -// the right message type or if it is not a map field. -// -// If the map field does not contain the requested key, this method returns -// nil, nil. The Go type of the value returned mirrors the type that protoc -// would generate for the field. (See TryGetField for more details on types). -// -// If the given field descriptor is not known (e.g. not present in the message -// descriptor) but corresponds to an unknown field, the unknown value will be -// parsed and become known. The parsed value will be searched for the requested -// key and any value returned. An error will be returned if the unknown value -// cannot be parsed according to the field descriptor's type information. -func (m *Message) TryGetMapField(fd *desc.FieldDescriptor, key interface{}) (interface{}, error) { - if err := m.checkField(fd); err != nil { - return nil, err - } - return m.getMapField(fd, key) -} - -// GetMapFieldByName returns the value for the map field with the given name and -// given key. It panics if an error is encountered. See TryGetMapFieldByName. -func (m *Message) GetMapFieldByName(name string, key interface{}) interface{} { - if v, err := m.TryGetMapFieldByName(name, key); err != nil { - panic(err.Error()) - } else { - return v - } -} - -// TryGetMapFieldByName returns the value for the map field with the given name -// and given key. An error is returned if the given name is unknown or if it -// names a field that is not a map field. -// -// If this message has no value for the given field or the value has no value -// for the requested key, then this method returns nil, nil. -// -// (See TryGetField for more info on types.) -func (m *Message) TryGetMapFieldByName(name string, key interface{}) (interface{}, error) { - fd := m.FindFieldDescriptorByName(name) - if fd == nil { - return nil, UnknownFieldNameError - } - return m.getMapField(fd, key) -} - -// GetMapFieldByNumber returns the value for the map field with the given tag -// number and given key. It panics if an error is encountered. See -// TryGetMapFieldByNumber. -func (m *Message) GetMapFieldByNumber(tagNumber int, key interface{}) interface{} { - if v, err := m.TryGetMapFieldByNumber(tagNumber, key); err != nil { - panic(err.Error()) - } else { - return v - } -} - -// TryGetMapFieldByNumber returns the value for the map field with the given tag -// number and given key. An error is returned if the given tag is unknown or if -// it indicates a field that is not a map field. -// -// If this message has no value for the given field or the value has no value -// for the requested key, then this method returns nil, nil. -// -// (See TryGetField for more info on types.) -func (m *Message) TryGetMapFieldByNumber(tagNumber int, key interface{}) (interface{}, error) { - fd := m.FindFieldDescriptor(int32(tagNumber)) - if fd == nil { - return nil, UnknownTagNumberError - } - return m.getMapField(fd, key) -} - -func (m *Message) getMapField(fd *desc.FieldDescriptor, key interface{}) (interface{}, error) { - if !fd.IsMap() { - return nil, FieldIsNotMapError - } - kfd := fd.GetMessageType().GetFields()[0] - ki, err := validElementFieldValue(kfd, key, false) - if err != nil { - return nil, err - } - mp := m.values[fd.GetNumber()] - if mp == nil { - if mp, err = m.parseUnknownField(fd); err != nil { - return nil, err - } else if mp == nil { - return nil, nil - } - } - return mp.(map[interface{}]interface{})[ki], nil -} - -// ForEachMapFieldEntry executes the given function for each entry in the map -// value for the given field descriptor. It stops iteration if the function -// returns false. It panics if an error is encountered. See -// TryForEachMapFieldEntry. -func (m *Message) ForEachMapFieldEntry(fd *desc.FieldDescriptor, fn func(key, val interface{}) bool) { - if err := m.TryForEachMapFieldEntry(fd, fn); err != nil { - panic(err.Error()) - } -} - -// TryForEachMapFieldEntry executes the given function for each entry in the map -// value for the given field descriptor. An error is returned if the given field -// descriptor does not belong to the right message type or if it is not a map -// field. -// -// Iteration ends either when all entries have been examined or when the given -// function returns false. So the function is expected to return true for normal -// iteration and false to break out. If this message has no value for the given -// field, it returns without invoking the given function. -// -// The Go type of the key and value supplied to the function mirrors the type -// that protoc would generate for the field. (See TryGetField for more details -// on types). -// -// If the given field descriptor is not known (e.g. not present in the message -// descriptor) but corresponds to an unknown field, the unknown value will be -// parsed and become known. The parsed value will be searched for the requested -// key and any value returned. An error will be returned if the unknown value -// cannot be parsed according to the field descriptor's type information. -func (m *Message) TryForEachMapFieldEntry(fd *desc.FieldDescriptor, fn func(key, val interface{}) bool) error { - if err := m.checkField(fd); err != nil { - return err - } - return m.forEachMapFieldEntry(fd, fn) -} - -// ForEachMapFieldEntryByName executes the given function for each entry in the -// map value for the field with the given name. It stops iteration if the -// function returns false. It panics if an error is encountered. See -// TryForEachMapFieldEntryByName. -func (m *Message) ForEachMapFieldEntryByName(name string, fn func(key, val interface{}) bool) { - if err := m.TryForEachMapFieldEntryByName(name, fn); err != nil { - panic(err.Error()) - } -} - -// TryForEachMapFieldEntryByName executes the given function for each entry in -// the map value for the field with the given name. It stops iteration if the -// function returns false. An error is returned if the given name is unknown or -// if it names a field that is not a map field. -// -// If this message has no value for the given field, it returns without ever -// invoking the given function. -// -// (See TryGetField for more info on types supplied to the function.) -func (m *Message) TryForEachMapFieldEntryByName(name string, fn func(key, val interface{}) bool) error { - fd := m.FindFieldDescriptorByName(name) - if fd == nil { - return UnknownFieldNameError - } - return m.forEachMapFieldEntry(fd, fn) -} - -// ForEachMapFieldEntryByNumber executes the given function for each entry in -// the map value for the field with the given tag number. It stops iteration if -// the function returns false. It panics if an error is encountered. See -// TryForEachMapFieldEntryByNumber. -func (m *Message) ForEachMapFieldEntryByNumber(tagNumber int, fn func(key, val interface{}) bool) { - if err := m.TryForEachMapFieldEntryByNumber(tagNumber, fn); err != nil { - panic(err.Error()) - } -} - -// TryForEachMapFieldEntryByNumber executes the given function for each entry in -// the map value for the field with the given tag number. It stops iteration if -// the function returns false. An error is returned if the given tag is unknown -// or if it indicates a field that is not a map field. -// -// If this message has no value for the given field, it returns without ever -// invoking the given function. -// -// (See TryGetField for more info on types supplied to the function.) -func (m *Message) TryForEachMapFieldEntryByNumber(tagNumber int, fn func(key, val interface{}) bool) error { - fd := m.FindFieldDescriptor(int32(tagNumber)) - if fd == nil { - return UnknownTagNumberError - } - return m.forEachMapFieldEntry(fd, fn) -} - -func (m *Message) forEachMapFieldEntry(fd *desc.FieldDescriptor, fn func(key, val interface{}) bool) error { - if !fd.IsMap() { - return FieldIsNotMapError - } - mp := m.values[fd.GetNumber()] - if mp == nil { - if mp, err := m.parseUnknownField(fd); err != nil { - return err - } else if mp == nil { - return nil - } - } - for k, v := range mp.(map[interface{}]interface{}) { - if !fn(k, v) { - break - } - } - return nil -} - -// PutMapField sets the value for the given map field descriptor and given key -// to the given value. It panics if an error is encountered. See TryPutMapField. -func (m *Message) PutMapField(fd *desc.FieldDescriptor, key interface{}, val interface{}) { - if err := m.TryPutMapField(fd, key, val); err != nil { - panic(err.Error()) - } -} - -// TryPutMapField sets the value for the given map field descriptor and given -// key to the given value. An error is returned if the given field descriptor -// does not belong to the right message type, if the given field is not a map -// field, or if the given value is not a correct/compatible type for the given -// field. -// -// The Go type expected for a field is the same as required by TrySetField for -// a field with the same type as the map's value type. -// -// If the given field descriptor is not known (e.g. not present in the message -// descriptor) it will become known. Subsequent operations using tag numbers or -// names will be able to resolve the newly-known type. If the message has a -// value for the unknown value, it is cleared, replaced by the given known -// value. -func (m *Message) TryPutMapField(fd *desc.FieldDescriptor, key interface{}, val interface{}) error { - if err := m.checkField(fd); err != nil { - return err - } - return m.putMapField(fd, key, val) -} - -// PutMapFieldByName sets the value for the map field with the given name and -// given key to the given value. It panics if an error is encountered. See -// TryPutMapFieldByName. -func (m *Message) PutMapFieldByName(name string, key interface{}, val interface{}) { - if err := m.TryPutMapFieldByName(name, key, val); err != nil { - panic(err.Error()) - } -} - -// TryPutMapFieldByName sets the value for the map field with the given name and -// the given key to the given value. An error is returned if the given name is -// unknown, if it names a field that is not a map, or if the given value has an -// incorrect type. -// -// (See TrySetField for more info on types.) -func (m *Message) TryPutMapFieldByName(name string, key interface{}, val interface{}) error { - fd := m.FindFieldDescriptorByName(name) - if fd == nil { - return UnknownFieldNameError - } - return m.putMapField(fd, key, val) -} - -// PutMapFieldByNumber sets the value for the map field with the given tag -// number and given key to the given value. It panics if an error is -// encountered. See TryPutMapFieldByNumber. -func (m *Message) PutMapFieldByNumber(tagNumber int, key interface{}, val interface{}) { - if err := m.TryPutMapFieldByNumber(tagNumber, key, val); err != nil { - panic(err.Error()) - } -} - -// TryPutMapFieldByNumber sets the value for the map field with the given tag -// number and the given key to the given value. An error is returned if the -// given tag is unknown, if it indicates a field that is not a map, or if the -// given value has an incorrect type. -// -// (See TrySetField for more info on types.) -func (m *Message) TryPutMapFieldByNumber(tagNumber int, key interface{}, val interface{}) error { - fd := m.FindFieldDescriptor(int32(tagNumber)) - if fd == nil { - return UnknownTagNumberError - } - return m.putMapField(fd, key, val) -} - -func (m *Message) putMapField(fd *desc.FieldDescriptor, key interface{}, val interface{}) error { - if !fd.IsMap() { - return FieldIsNotMapError - } - kfd := fd.GetMessageType().GetFields()[0] - ki, err := validElementFieldValue(kfd, key, false) - if err != nil { - return err - } - vfd := fd.GetMessageType().GetFields()[1] - vi, err := validElementFieldValue(vfd, val, true) - if err != nil { - return err - } - mp := m.values[fd.GetNumber()] - if mp == nil { - if mp, err = m.parseUnknownField(fd); err != nil { - return err - } else if mp == nil { - m.internalSetField(fd, map[interface{}]interface{}{ki: vi}) - return nil - } - } - mp.(map[interface{}]interface{})[ki] = vi - return nil -} - -// RemoveMapField changes the value for the given field descriptor by removing -// any value associated with the given key. It panics if an error is -// encountered. See TryRemoveMapField. -func (m *Message) RemoveMapField(fd *desc.FieldDescriptor, key interface{}) { - if err := m.TryRemoveMapField(fd, key); err != nil { - panic(err.Error()) - } -} - -// TryRemoveMapField changes the value for the given field descriptor by -// removing any value associated with the given key. An error is returned if the -// given field descriptor does not belong to the right message type or if the -// given field is not a map field. -// -// If the given field descriptor is not known (e.g. not present in the message -// descriptor) it will become known. Subsequent operations using tag numbers or -// names will be able to resolve the newly-known type. If the message has a -// value for the unknown value, it is parsed and any value for the given key -// removed. -func (m *Message) TryRemoveMapField(fd *desc.FieldDescriptor, key interface{}) error { - if err := m.checkField(fd); err != nil { - return err - } - return m.removeMapField(fd, key) -} - -// RemoveMapFieldByName changes the value for the field with the given name by -// removing any value associated with the given key. It panics if an error is -// encountered. See TryRemoveMapFieldByName. -func (m *Message) RemoveMapFieldByName(name string, key interface{}) { - if err := m.TryRemoveMapFieldByName(name, key); err != nil { - panic(err.Error()) - } -} - -// TryRemoveMapFieldByName changes the value for the field with the given name -// by removing any value associated with the given key. An error is returned if -// the given name is unknown or if it names a field that is not a map. -func (m *Message) TryRemoveMapFieldByName(name string, key interface{}) error { - fd := m.FindFieldDescriptorByName(name) - if fd == nil { - return UnknownFieldNameError - } - return m.removeMapField(fd, key) -} - -// RemoveMapFieldByNumber changes the value for the field with the given tag -// number by removing any value associated with the given key. It panics if an -// error is encountered. See TryRemoveMapFieldByNumber. -func (m *Message) RemoveMapFieldByNumber(tagNumber int, key interface{}) { - if err := m.TryRemoveMapFieldByNumber(tagNumber, key); err != nil { - panic(err.Error()) - } -} - -// TryRemoveMapFieldByNumber changes the value for the field with the given tag -// number by removing any value associated with the given key. An error is -// returned if the given tag is unknown or if it indicates a field that is not -// a map. -func (m *Message) TryRemoveMapFieldByNumber(tagNumber int, key interface{}) error { - fd := m.FindFieldDescriptor(int32(tagNumber)) - if fd == nil { - return UnknownTagNumberError - } - return m.removeMapField(fd, key) -} - -func (m *Message) removeMapField(fd *desc.FieldDescriptor, key interface{}) error { - if !fd.IsMap() { - return FieldIsNotMapError - } - kfd := fd.GetMessageType().GetFields()[0] - ki, err := validElementFieldValue(kfd, key, false) - if err != nil { - return err - } - mp := m.values[fd.GetNumber()] - if mp == nil { - if mp, err = m.parseUnknownField(fd); err != nil { - return err - } else if mp == nil { - return nil - } - } - res := mp.(map[interface{}]interface{}) - delete(res, ki) - if len(res) == 0 { - delete(m.values, fd.GetNumber()) - } - return nil -} - -// FieldLength returns the number of elements in this message for the given -// field descriptor. It panics if an error is encountered. See TryFieldLength. -func (m *Message) FieldLength(fd *desc.FieldDescriptor) int { - l, err := m.TryFieldLength(fd) - if err != nil { - panic(err.Error()) - } - return l -} - -// TryFieldLength returns the number of elements in this message for the given -// field descriptor. An error is returned if the given field descriptor does not -// belong to the right message type or if it is neither a map field nor a -// repeated field. -func (m *Message) TryFieldLength(fd *desc.FieldDescriptor) (int, error) { - if err := m.checkField(fd); err != nil { - return 0, err - } - return m.fieldLength(fd) -} - -// FieldLengthByName returns the number of elements in this message for the -// field with the given name. It panics if an error is encountered. See -// TryFieldLengthByName. -func (m *Message) FieldLengthByName(name string) int { - l, err := m.TryFieldLengthByName(name) - if err != nil { - panic(err.Error()) - } - return l -} - -// TryFieldLengthByName returns the number of elements in this message for the -// field with the given name. An error is returned if the given name is unknown -// or if the named field is neither a map field nor a repeated field. -func (m *Message) TryFieldLengthByName(name string) (int, error) { - fd := m.FindFieldDescriptorByName(name) - if fd == nil { - return 0, UnknownFieldNameError - } - return m.fieldLength(fd) -} - -// FieldLengthByNumber returns the number of elements in this message for the -// field with the given tag number. It panics if an error is encountered. See -// TryFieldLengthByNumber. -func (m *Message) FieldLengthByNumber(tagNumber int32) int { - l, err := m.TryFieldLengthByNumber(tagNumber) - if err != nil { - panic(err.Error()) - } - return l -} - -// TryFieldLengthByNumber returns the number of elements in this message for the -// field with the given tag number. An error is returned if the given tag is -// unknown or if the named field is neither a map field nor a repeated field. -func (m *Message) TryFieldLengthByNumber(tagNumber int32) (int, error) { - fd := m.FindFieldDescriptor(int32(tagNumber)) - if fd == nil { - return 0, UnknownTagNumberError - } - return m.fieldLength(fd) -} - -func (m *Message) fieldLength(fd *desc.FieldDescriptor) (int, error) { - if !fd.IsRepeated() { - return 0, FieldIsNotRepeatedError - } - val := m.values[fd.GetNumber()] - if val == nil { - var err error - if val, err = m.parseUnknownField(fd); err != nil { - return 0, err - } else if val == nil { - return 0, nil - } - } - if sl, ok := val.([]interface{}); ok { - return len(sl), nil - } else if mp, ok := val.(map[interface{}]interface{}); ok { - return len(mp), nil - } - return 0, nil -} - -// GetRepeatedField returns the value for the given repeated field descriptor at -// the given index. It panics if an error is encountered. See -// TryGetRepeatedField. -func (m *Message) GetRepeatedField(fd *desc.FieldDescriptor, index int) interface{} { - if v, err := m.TryGetRepeatedField(fd, index); err != nil { - panic(err.Error()) - } else { - return v - } -} - -// TryGetRepeatedField returns the value for the given repeated field descriptor -// at the given index. An error is returned if the given field descriptor does -// not belong to the right message type, if it is not a repeated field, or if -// the given index is out of range (less than zero or greater than or equal to -// the length of the repeated field). Also, even though map fields technically -// are repeated fields, if the given field is a map field an error will result: -// map representation does not lend itself to random access by index. -// -// The Go type of the value returned mirrors the type that protoc would generate -// for the field's element type. (See TryGetField for more details on types). -// -// If the given field descriptor is not known (e.g. not present in the message -// descriptor) but corresponds to an unknown field, the unknown value will be -// parsed and become known. The value at the given index in the parsed value -// will be returned. An error will be returned if the unknown value cannot be -// parsed according to the field descriptor's type information. -func (m *Message) TryGetRepeatedField(fd *desc.FieldDescriptor, index int) (interface{}, error) { - if index < 0 { - return nil, IndexOutOfRangeError - } - if err := m.checkField(fd); err != nil { - return nil, err - } - return m.getRepeatedField(fd, index) -} - -// GetRepeatedFieldByName returns the value for the repeated field with the -// given name at the given index. It panics if an error is encountered. See -// TryGetRepeatedFieldByName. -func (m *Message) GetRepeatedFieldByName(name string, index int) interface{} { - if v, err := m.TryGetRepeatedFieldByName(name, index); err != nil { - panic(err.Error()) - } else { - return v - } -} - -// TryGetRepeatedFieldByName returns the value for the repeated field with the -// given name at the given index. An error is returned if the given name is -// unknown, if it names a field that is not a repeated field (or is a map -// field), or if the given index is out of range (less than zero or greater -// than or equal to the length of the repeated field). -// -// (See TryGetField for more info on types.) -func (m *Message) TryGetRepeatedFieldByName(name string, index int) (interface{}, error) { - if index < 0 { - return nil, IndexOutOfRangeError - } - fd := m.FindFieldDescriptorByName(name) - if fd == nil { - return nil, UnknownFieldNameError - } - return m.getRepeatedField(fd, index) -} - -// GetRepeatedFieldByNumber returns the value for the repeated field with the -// given tag number at the given index. It panics if an error is encountered. -// See TryGetRepeatedFieldByNumber. -func (m *Message) GetRepeatedFieldByNumber(tagNumber int, index int) interface{} { - if v, err := m.TryGetRepeatedFieldByNumber(tagNumber, index); err != nil { - panic(err.Error()) - } else { - return v - } -} - -// TryGetRepeatedFieldByNumber returns the value for the repeated field with the -// given tag number at the given index. An error is returned if the given tag is -// unknown, if it indicates a field that is not a repeated field (or is a map -// field), or if the given index is out of range (less than zero or greater than -// or equal to the length of the repeated field). -// -// (See TryGetField for more info on types.) -func (m *Message) TryGetRepeatedFieldByNumber(tagNumber int, index int) (interface{}, error) { - if index < 0 { - return nil, IndexOutOfRangeError - } - fd := m.FindFieldDescriptor(int32(tagNumber)) - if fd == nil { - return nil, UnknownTagNumberError - } - return m.getRepeatedField(fd, index) -} - -func (m *Message) getRepeatedField(fd *desc.FieldDescriptor, index int) (interface{}, error) { - if fd.IsMap() || !fd.IsRepeated() { - return nil, FieldIsNotRepeatedError - } - sl := m.values[fd.GetNumber()] - if sl == nil { - var err error - if sl, err = m.parseUnknownField(fd); err != nil { - return nil, err - } else if sl == nil { - return nil, IndexOutOfRangeError - } - } - res := sl.([]interface{}) - if index >= len(res) { - return nil, IndexOutOfRangeError - } - return res[index], nil -} - -// AddRepeatedField appends the given value to the given repeated field. It -// panics if an error is encountered. See TryAddRepeatedField. -func (m *Message) AddRepeatedField(fd *desc.FieldDescriptor, val interface{}) { - if err := m.TryAddRepeatedField(fd, val); err != nil { - panic(err.Error()) - } -} - -// TryAddRepeatedField appends the given value to the given repeated field. An -// error is returned if the given field descriptor does not belong to the right -// message type, if the given field is not repeated, or if the given value is -// not a correct/compatible type for the given field. If the given field is a -// map field, the call will succeed if the given value is an instance of the -// map's entry message type. -// -// The Go type expected for a field is the same as required by TrySetField for -// a non-repeated field of the same type. -// -// If the given field descriptor is not known (e.g. not present in the message -// descriptor) it will become known. Subsequent operations using tag numbers or -// names will be able to resolve the newly-known type. If the message has a -// value for the unknown value, it is parsed and the given value is appended to -// it. -func (m *Message) TryAddRepeatedField(fd *desc.FieldDescriptor, val interface{}) error { - if err := m.checkField(fd); err != nil { - return err - } - return m.addRepeatedField(fd, val) -} - -// AddRepeatedFieldByName appends the given value to the repeated field with the -// given name. It panics if an error is encountered. See -// TryAddRepeatedFieldByName. -func (m *Message) AddRepeatedFieldByName(name string, val interface{}) { - if err := m.TryAddRepeatedFieldByName(name, val); err != nil { - panic(err.Error()) - } -} - -// TryAddRepeatedFieldByName appends the given value to the repeated field with -// the given name. An error is returned if the given name is unknown, if it -// names a field that is not repeated, or if the given value has an incorrect -// type. -// -// (See TrySetField for more info on types.) -func (m *Message) TryAddRepeatedFieldByName(name string, val interface{}) error { - fd := m.FindFieldDescriptorByName(name) - if fd == nil { - return UnknownFieldNameError - } - return m.addRepeatedField(fd, val) -} - -// AddRepeatedFieldByNumber appends the given value to the repeated field with -// the given tag number. It panics if an error is encountered. See -// TryAddRepeatedFieldByNumber. -func (m *Message) AddRepeatedFieldByNumber(tagNumber int, val interface{}) { - if err := m.TryAddRepeatedFieldByNumber(tagNumber, val); err != nil { - panic(err.Error()) - } -} - -// TryAddRepeatedFieldByNumber appends the given value to the repeated field -// with the given tag number. An error is returned if the given tag is unknown, -// if it indicates a field that is not repeated, or if the given value has an -// incorrect type. -// -// (See TrySetField for more info on types.) -func (m *Message) TryAddRepeatedFieldByNumber(tagNumber int, val interface{}) error { - fd := m.FindFieldDescriptor(int32(tagNumber)) - if fd == nil { - return UnknownTagNumberError - } - return m.addRepeatedField(fd, val) -} - -func (m *Message) addRepeatedField(fd *desc.FieldDescriptor, val interface{}) error { - if !fd.IsRepeated() { - return FieldIsNotRepeatedError - } - val, err := validElementFieldValue(fd, val, false) - if err != nil { - return err - } - - if fd.IsMap() { - // We're lenient. Just as we allow setting a map field to a slice of entry messages, we also allow - // adding entries one at a time (as if the field were a normal repeated field). - msg := val.(proto.Message) - dm, err := asDynamicMessage(msg, fd.GetMessageType(), m.mf) - if err != nil { - return err - } - k, err := dm.TryGetFieldByNumber(1) - if err != nil { - return err - } - v, err := dm.TryGetFieldByNumber(2) - if err != nil { - return err - } - return m.putMapField(fd, k, v) - } - - sl := m.values[fd.GetNumber()] - if sl == nil { - if sl, err = m.parseUnknownField(fd); err != nil { - return err - } else if sl == nil { - sl = []interface{}{} - } - } - res := sl.([]interface{}) - res = append(res, val) - m.internalSetField(fd, res) - return nil -} - -// SetRepeatedField sets the value for the given repeated field descriptor and -// given index to the given value. It panics if an error is encountered. See -// SetRepeatedField. -func (m *Message) SetRepeatedField(fd *desc.FieldDescriptor, index int, val interface{}) { - if err := m.TrySetRepeatedField(fd, index, val); err != nil { - panic(err.Error()) - } -} - -// TrySetRepeatedField sets the value for the given repeated field descriptor -// and given index to the given value. An error is returned if the given field -// descriptor does not belong to the right message type, if the given field is -// not repeated, or if the given value is not a correct/compatible type for the -// given field. Also, even though map fields technically are repeated fields, if -// the given field is a map field an error will result: map representation does -// not lend itself to random access by index. -// -// The Go type expected for a field is the same as required by TrySetField for -// a non-repeated field of the same type. -// -// If the given field descriptor is not known (e.g. not present in the message -// descriptor) it will become known. Subsequent operations using tag numbers or -// names will be able to resolve the newly-known type. If the message has a -// value for the unknown value, it is parsed and the element at the given index -// is replaced with the given value. -func (m *Message) TrySetRepeatedField(fd *desc.FieldDescriptor, index int, val interface{}) error { - if index < 0 { - return IndexOutOfRangeError - } - if err := m.checkField(fd); err != nil { - return err - } - return m.setRepeatedField(fd, index, val) -} - -// SetRepeatedFieldByName sets the value for the repeated field with the given -// name and given index to the given value. It panics if an error is -// encountered. See TrySetRepeatedFieldByName. -func (m *Message) SetRepeatedFieldByName(name string, index int, val interface{}) { - if err := m.TrySetRepeatedFieldByName(name, index, val); err != nil { - panic(err.Error()) - } -} - -// TrySetRepeatedFieldByName sets the value for the repeated field with the -// given name and the given index to the given value. An error is returned if -// the given name is unknown, if it names a field that is not repeated (or is a -// map field), or if the given value has an incorrect type. -// -// (See TrySetField for more info on types.) -func (m *Message) TrySetRepeatedFieldByName(name string, index int, val interface{}) error { - if index < 0 { - return IndexOutOfRangeError - } - fd := m.FindFieldDescriptorByName(name) - if fd == nil { - return UnknownFieldNameError - } - return m.setRepeatedField(fd, index, val) -} - -// SetRepeatedFieldByNumber sets the value for the repeated field with the given -// tag number and given index to the given value. It panics if an error is -// encountered. See TrySetRepeatedFieldByNumber. -func (m *Message) SetRepeatedFieldByNumber(tagNumber int, index int, val interface{}) { - if err := m.TrySetRepeatedFieldByNumber(tagNumber, index, val); err != nil { - panic(err.Error()) - } -} - -// TrySetRepeatedFieldByNumber sets the value for the repeated field with the -// given tag number and the given index to the given value. An error is returned -// if the given tag is unknown, if it indicates a field that is not repeated (or -// is a map field), or if the given value has an incorrect type. -// -// (See TrySetField for more info on types.) -func (m *Message) TrySetRepeatedFieldByNumber(tagNumber int, index int, val interface{}) error { - if index < 0 { - return IndexOutOfRangeError - } - fd := m.FindFieldDescriptor(int32(tagNumber)) - if fd == nil { - return UnknownTagNumberError - } - return m.setRepeatedField(fd, index, val) -} - -func (m *Message) setRepeatedField(fd *desc.FieldDescriptor, index int, val interface{}) error { - if fd.IsMap() || !fd.IsRepeated() { - return FieldIsNotRepeatedError - } - val, err := validElementFieldValue(fd, val, false) - if err != nil { - return err - } - sl := m.values[fd.GetNumber()] - if sl == nil { - if sl, err = m.parseUnknownField(fd); err != nil { - return err - } else if sl == nil { - return IndexOutOfRangeError - } - } - res := sl.([]interface{}) - if index >= len(res) { - return IndexOutOfRangeError - } - res[index] = val - return nil -} - -// GetUnknownField gets the value(s) for the given unknown tag number. If this -// message has no unknown fields with the given tag, nil is returned. -func (m *Message) GetUnknownField(tagNumber int32) []UnknownField { - if u, ok := m.unknownFields[tagNumber]; ok { - return u - } else { - return nil - } -} - -func (m *Message) parseUnknownField(fd *desc.FieldDescriptor) (interface{}, error) { - unks, ok := m.unknownFields[fd.GetNumber()] - if !ok { - return nil, nil - } - var v interface{} - var sl []interface{} - var mp map[interface{}]interface{} - if fd.IsMap() { - mp = map[interface{}]interface{}{} - } - var err error - for _, unk := range unks { - var val interface{} - if unk.Encoding == proto.WireBytes || unk.Encoding == proto.WireStartGroup { - val, err = codec.DecodeLengthDelimitedField(fd, unk.Contents, m.mf) - } else { - val, err = codec.DecodeScalarField(fd, unk.Value) - } - if err != nil { - return nil, err - } - if fd.IsMap() { - newEntry := val.(*Message) - kk, err := newEntry.TryGetFieldByNumber(1) - if err != nil { - return nil, err - } - vv, err := newEntry.TryGetFieldByNumber(2) - if err != nil { - return nil, err - } - mp[kk] = vv - v = mp - } else if fd.IsRepeated() { - t := reflect.TypeOf(val) - if t.Kind() == reflect.Slice && t != typeOfBytes { - // append slices if we unmarshalled a packed repeated field - newVals := val.([]interface{}) - sl = append(sl, newVals...) - } else { - sl = append(sl, val) - } - v = sl - } else { - v = val - } - } - m.internalSetField(fd, v) - return v, nil -} - -func validFieldValue(fd *desc.FieldDescriptor, val interface{}) (interface{}, error) { - return validFieldValueForRv(fd, reflect.ValueOf(val)) -} - -func validFieldValueForRv(fd *desc.FieldDescriptor, val reflect.Value) (interface{}, error) { - if fd.IsMap() && val.Kind() == reflect.Map { - return validFieldValueForMapField(fd, val) - } - - if fd.IsRepeated() { // this will also catch map fields where given value was not a map - if val.Kind() != reflect.Array && val.Kind() != reflect.Slice { - if fd.IsMap() { - return nil, fmt.Errorf("value for map field must be a map; instead was %v", val.Type()) - } else { - return nil, fmt.Errorf("value for repeated field must be a slice; instead was %v", val.Type()) - } - } - - if fd.IsMap() { - // value should be a slice of entry messages that we need convert into a map[interface{}]interface{} - m := map[interface{}]interface{}{} - for i := 0; i < val.Len(); i++ { - e, err := validElementFieldValue(fd, val.Index(i).Interface(), false) - if err != nil { - return nil, err - } - msg := e.(proto.Message) - dm, err := asDynamicMessage(msg, fd.GetMessageType(), nil) - if err != nil { - return nil, err - } - k, err := dm.TryGetFieldByNumber(1) - if err != nil { - return nil, err - } - v, err := dm.TryGetFieldByNumber(2) - if err != nil { - return nil, err - } - m[k] = v - } - return m, nil - } - - // make a defensive copy while checking contents (also converts to []interface{}) - s := make([]interface{}, val.Len()) - for i := 0; i < val.Len(); i++ { - ev := val.Index(i) - if ev.Kind() == reflect.Interface { - // unwrap it - ev = reflect.ValueOf(ev.Interface()) - } - e, err := validElementFieldValueForRv(fd, ev, false) - if err != nil { - return nil, err - } - s[i] = e - } - - return s, nil - } - - return validElementFieldValueForRv(fd, val, false) -} - -func asDynamicMessage(m proto.Message, md *desc.MessageDescriptor, mf *MessageFactory) (*Message, error) { - if dm, ok := m.(*Message); ok { - return dm, nil - } - dm := NewMessageWithMessageFactory(md, mf) - if err := dm.mergeFrom(m); err != nil { - return nil, err - } - return dm, nil -} - -func validElementFieldValue(fd *desc.FieldDescriptor, val interface{}, allowNilMessage bool) (interface{}, error) { - return validElementFieldValueForRv(fd, reflect.ValueOf(val), allowNilMessage) -} - -func validElementFieldValueForRv(fd *desc.FieldDescriptor, val reflect.Value, allowNilMessage bool) (interface{}, error) { - t := fd.GetType() - if !val.IsValid() { - return nil, typeError(fd, nil) - } - - switch t { - case descriptorpb.FieldDescriptorProto_TYPE_SFIXED32, - descriptorpb.FieldDescriptorProto_TYPE_INT32, - descriptorpb.FieldDescriptorProto_TYPE_SINT32, - descriptorpb.FieldDescriptorProto_TYPE_ENUM: - return toInt32(reflect.Indirect(val), fd) - - case descriptorpb.FieldDescriptorProto_TYPE_SFIXED64, - descriptorpb.FieldDescriptorProto_TYPE_INT64, - descriptorpb.FieldDescriptorProto_TYPE_SINT64: - return toInt64(reflect.Indirect(val), fd) - - case descriptorpb.FieldDescriptorProto_TYPE_FIXED32, - descriptorpb.FieldDescriptorProto_TYPE_UINT32: - return toUint32(reflect.Indirect(val), fd) - - case descriptorpb.FieldDescriptorProto_TYPE_FIXED64, - descriptorpb.FieldDescriptorProto_TYPE_UINT64: - return toUint64(reflect.Indirect(val), fd) - - case descriptorpb.FieldDescriptorProto_TYPE_FLOAT: - return toFloat32(reflect.Indirect(val), fd) - - case descriptorpb.FieldDescriptorProto_TYPE_DOUBLE: - return toFloat64(reflect.Indirect(val), fd) - - case descriptorpb.FieldDescriptorProto_TYPE_BOOL: - return toBool(reflect.Indirect(val), fd) - - case descriptorpb.FieldDescriptorProto_TYPE_BYTES: - return toBytes(reflect.Indirect(val), fd) - - case descriptorpb.FieldDescriptorProto_TYPE_STRING: - return toString(reflect.Indirect(val), fd) - - case descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, - descriptorpb.FieldDescriptorProto_TYPE_GROUP: - m, err := asMessage(val, fd.GetFullyQualifiedName()) - // check that message is correct type - if err != nil { - return nil, err - } - var msgType string - if dm, ok := m.(*Message); ok { - if allowNilMessage && dm == nil { - // if dm == nil, we'll panic below, so early out if that is allowed - // (only allowed for map values, to indicate an entry w/ no value) - return m, nil - } - msgType = dm.GetMessageDescriptor().GetFullyQualifiedName() - } else { - msgType = proto.MessageName(m) - } - if msgType != fd.GetMessageType().GetFullyQualifiedName() { - return nil, fmt.Errorf("message field %s requires value of type %s; received %s", fd.GetFullyQualifiedName(), fd.GetMessageType().GetFullyQualifiedName(), msgType) - } - return m, nil - - default: - return nil, fmt.Errorf("unable to handle unrecognized field type: %v", fd.GetType()) - } -} - -func toInt32(v reflect.Value, fd *desc.FieldDescriptor) (int32, error) { - if v.Kind() == reflect.Int32 { - return int32(v.Int()), nil - } - return 0, typeError(fd, v.Type()) -} - -func toUint32(v reflect.Value, fd *desc.FieldDescriptor) (uint32, error) { - if v.Kind() == reflect.Uint32 { - return uint32(v.Uint()), nil - } - return 0, typeError(fd, v.Type()) -} - -func toFloat32(v reflect.Value, fd *desc.FieldDescriptor) (float32, error) { - if v.Kind() == reflect.Float32 { - return float32(v.Float()), nil - } - return 0, typeError(fd, v.Type()) -} - -func toInt64(v reflect.Value, fd *desc.FieldDescriptor) (int64, error) { - if v.Kind() == reflect.Int64 || v.Kind() == reflect.Int || v.Kind() == reflect.Int32 { - return v.Int(), nil - } - return 0, typeError(fd, v.Type()) -} - -func toUint64(v reflect.Value, fd *desc.FieldDescriptor) (uint64, error) { - if v.Kind() == reflect.Uint64 || v.Kind() == reflect.Uint || v.Kind() == reflect.Uint32 { - return v.Uint(), nil - } - return 0, typeError(fd, v.Type()) -} - -func toFloat64(v reflect.Value, fd *desc.FieldDescriptor) (float64, error) { - if v.Kind() == reflect.Float64 || v.Kind() == reflect.Float32 { - return v.Float(), nil - } - return 0, typeError(fd, v.Type()) -} - -func toBool(v reflect.Value, fd *desc.FieldDescriptor) (bool, error) { - if v.Kind() == reflect.Bool { - return v.Bool(), nil - } - return false, typeError(fd, v.Type()) -} - -func toBytes(v reflect.Value, fd *desc.FieldDescriptor) ([]byte, error) { - if v.Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8 { - return v.Bytes(), nil - } - return nil, typeError(fd, v.Type()) -} - -func toString(v reflect.Value, fd *desc.FieldDescriptor) (string, error) { - if v.Kind() == reflect.String { - return v.String(), nil - } - return "", typeError(fd, v.Type()) -} - -func typeError(fd *desc.FieldDescriptor, t reflect.Type) error { - return fmt.Errorf( - "%s field %s is not compatible with value of type %v", - getTypeString(fd), fd.GetFullyQualifiedName(), t) -} - -func getTypeString(fd *desc.FieldDescriptor) string { - return strings.ToLower(fd.GetType().String()) -} - -func asMessage(v reflect.Value, fieldName string) (proto.Message, error) { - t := v.Type() - // we need a pointer to a struct that implements proto.Message - if t.Kind() != reflect.Ptr || t.Elem().Kind() != reflect.Struct || !t.Implements(typeOfProtoMessage) { - return nil, fmt.Errorf("message field %s requires is not compatible with value of type %v", fieldName, v.Type()) - } - return v.Interface().(proto.Message), nil -} - -// Reset resets this message to an empty message. It removes all values set in -// the message. -func (m *Message) Reset() { - for k := range m.values { - delete(m.values, k) - } - for k := range m.unknownFields { - delete(m.unknownFields, k) - } -} - -// String returns this message rendered in compact text format. -func (m *Message) String() string { - b, err := m.MarshalText() - if err != nil { - panic(fmt.Sprintf("Failed to create string representation of message: %s", err.Error())) - } - return string(b) -} - -// ProtoMessage is present to satisfy the proto.Message interface. -func (m *Message) ProtoMessage() { -} - -// ConvertTo converts this dynamic message into the given message. This is -// shorthand for resetting then merging: -// -// target.Reset() -// m.MergeInto(target) -func (m *Message) ConvertTo(target proto.Message) error { - if err := m.checkType(target); err != nil { - return err - } - - target.Reset() - return m.mergeInto(target, defaultDeterminism) -} - -// ConvertToDeterministic converts this dynamic message into the given message. -// It is just like ConvertTo, but it attempts to produce deterministic results. -// That means that if the target is a generated message (not another dynamic -// message) and the current runtime is unaware of any fields or extensions that -// are present in m, they will be serialized into the target's unrecognized -// fields deterministically. -func (m *Message) ConvertToDeterministic(target proto.Message) error { - if err := m.checkType(target); err != nil { - return err - } - - target.Reset() - return m.mergeInto(target, true) -} - -// ConvertFrom converts the given message into this dynamic message. This is -// shorthand for resetting then merging: -// -// m.Reset() -// m.MergeFrom(target) -func (m *Message) ConvertFrom(target proto.Message) error { - if err := m.checkType(target); err != nil { - return err - } - - m.Reset() - return m.mergeFrom(target) -} - -// MergeInto merges this dynamic message into the given message. All field -// values in this message will be set on the given message. For map fields, -// entries are added to the given message (if the given message has existing -// values for like keys, they are overwritten). For slice fields, elements are -// added. -// -// If the given message has a different set of known fields, it is possible for -// some known fields in this message to be represented as unknown fields in the -// given message after merging, and vice versa. -func (m *Message) MergeInto(target proto.Message) error { - if err := m.checkType(target); err != nil { - return err - } - return m.mergeInto(target, defaultDeterminism) -} - -// MergeIntoDeterministic merges this dynamic message into the given message. -// It is just like MergeInto, but it attempts to produce deterministic results. -// That means that if the target is a generated message (not another dynamic -// message) and the current runtime is unaware of any fields or extensions that -// are present in m, they will be serialized into the target's unrecognized -// fields deterministically. -func (m *Message) MergeIntoDeterministic(target proto.Message) error { - if err := m.checkType(target); err != nil { - return err - } - return m.mergeInto(target, true) -} - -// MergeFrom merges the given message into this dynamic message. All field -// values in the given message will be set on this message. For map fields, -// entries are added to this message (if this message has existing values for -// like keys, they are overwritten). For slice fields, elements are added. -// -// If the given message has a different set of known fields, it is possible for -// some known fields in that message to be represented as unknown fields in this -// message after merging, and vice versa. -func (m *Message) MergeFrom(source proto.Message) error { - if err := m.checkType(source); err != nil { - return err - } - return m.mergeFrom(source) -} - -// Merge implements the proto.Merger interface so that dynamic messages are -// compatible with the proto.Merge function. It delegates to MergeFrom but will -// panic on error as the proto.Merger interface doesn't allow for returning an -// error. -// -// Unlike nearly all other methods, this method can work if this message's type -// is not defined (such as instantiating the message without using NewMessage). -// This is strictly so that dynamic message's are compatible with the -// proto.Clone function, which instantiates a new message via reflection (thus -// its message descriptor will not be set) and than calls Merge. -func (m *Message) Merge(source proto.Message) { - if m.md == nil { - // To support proto.Clone, initialize the descriptor from the source. - if dm, ok := source.(*Message); ok { - m.md = dm.md - // also make sure the clone uses the same message factory and - // extensions and also knows about the same extra fields (if any) - m.mf = dm.mf - m.er = dm.er - m.extraFields = dm.extraFields - } else if md, err := desc.LoadMessageDescriptorForMessage(source); err != nil { - panic(err.Error()) - } else { - m.md = md - } - } - - if err := m.MergeFrom(source); err != nil { - panic(err.Error()) - } -} - -func (m *Message) checkType(target proto.Message) error { - if dm, ok := target.(*Message); ok { - if dm.md.GetFullyQualifiedName() != m.md.GetFullyQualifiedName() { - return fmt.Errorf("given message has wrong type: %q; expecting %q", dm.md.GetFullyQualifiedName(), m.md.GetFullyQualifiedName()) - } - return nil - } - - msgName := proto.MessageName(target) - if msgName != m.md.GetFullyQualifiedName() { - return fmt.Errorf("given message has wrong type: %q; expecting %q", msgName, m.md.GetFullyQualifiedName()) - } - return nil -} - -func (m *Message) mergeInto(pm proto.Message, deterministic bool) error { - if dm, ok := pm.(*Message); ok { - return dm.mergeFrom(m) - } - - target := reflect.ValueOf(pm) - if target.Kind() == reflect.Ptr { - target = target.Elem() - } - - // track tags for which the dynamic message has data but the given - // message doesn't know about it - unknownTags := map[int32]struct{}{} - for tag := range m.values { - unknownTags[tag] = struct{}{} - } - - // check that we can successfully do the merge - structProps := proto.GetProperties(reflect.TypeOf(pm).Elem()) - for _, prop := range structProps.Prop { - if prop.Tag == 0 { - continue // one-of or special field (such as XXX_unrecognized, etc.) - } - tag := int32(prop.Tag) - v, ok := m.values[tag] - if !ok { - continue - } - if unknownTags != nil { - delete(unknownTags, tag) - } - f := target.FieldByName(prop.Name) - ft := f.Type() - val := reflect.ValueOf(v) - if !canConvert(val, ft) { - return fmt.Errorf("cannot convert %v to %v", val.Type(), ft) - } - } - // check one-of fields - for _, oop := range structProps.OneofTypes { - prop := oop.Prop - tag := int32(prop.Tag) - v, ok := m.values[tag] - if !ok { - continue - } - if unknownTags != nil { - delete(unknownTags, tag) - } - stf, ok := oop.Type.Elem().FieldByName(prop.Name) - if !ok { - return fmt.Errorf("one-of field indicates struct field name %s, but type %v has no such field", prop.Name, oop.Type.Elem()) - } - ft := stf.Type - val := reflect.ValueOf(v) - if !canConvert(val, ft) { - return fmt.Errorf("cannot convert %v to %v", val.Type(), ft) - } - } - // and check extensions, too - for tag, ext := range proto.RegisteredExtensions(pm) { - v, ok := m.values[tag] - if !ok { - continue - } - if unknownTags != nil { - delete(unknownTags, tag) - } - ft := reflect.TypeOf(ext.ExtensionType) - val := reflect.ValueOf(v) - if !canConvert(val, ft) { - return fmt.Errorf("cannot convert %v to %v", val.Type(), ft) - } - } - - // now actually perform the merge - for _, prop := range structProps.Prop { - v, ok := m.values[int32(prop.Tag)] - if !ok { - continue - } - f := target.FieldByName(prop.Name) - if err := mergeVal(reflect.ValueOf(v), f, deterministic); err != nil { - return err - } - } - // merge one-ofs - for _, oop := range structProps.OneofTypes { - prop := oop.Prop - tag := int32(prop.Tag) - v, ok := m.values[tag] - if !ok { - continue - } - oov := reflect.New(oop.Type.Elem()) - f := oov.Elem().FieldByName(prop.Name) - if err := mergeVal(reflect.ValueOf(v), f, deterministic); err != nil { - return err - } - target.Field(oop.Field).Set(oov) - } - // merge extensions, too - for tag, ext := range proto.RegisteredExtensions(pm) { - v, ok := m.values[tag] - if !ok { - continue - } - e := reflect.New(reflect.TypeOf(ext.ExtensionType)).Elem() - if err := mergeVal(reflect.ValueOf(v), e, deterministic); err != nil { - return err - } - if err := proto.SetExtension(pm, ext, e.Interface()); err != nil { - // shouldn't happen since we already checked that the extension type was compatible above - return err - } - } - - // if we have fields that the given message doesn't know about, add to its unknown fields - if len(unknownTags) > 0 { - var b codec.Buffer - b.SetDeterministic(deterministic) - if deterministic { - // if we need to emit things deterministically, sort the - // extensions by their tag number - sortedUnknownTags := make([]int32, 0, len(unknownTags)) - for tag := range unknownTags { - sortedUnknownTags = append(sortedUnknownTags, tag) - } - sort.Slice(sortedUnknownTags, func(i, j int) bool { - return sortedUnknownTags[i] < sortedUnknownTags[j] - }) - for _, tag := range sortedUnknownTags { - fd := m.FindFieldDescriptor(tag) - if err := b.EncodeFieldValue(fd, m.values[tag]); err != nil { - return err - } - } - } else { - for tag := range unknownTags { - fd := m.FindFieldDescriptor(tag) - if err := b.EncodeFieldValue(fd, m.values[tag]); err != nil { - return err - } - } - } - - internal.SetUnrecognized(pm, b.Bytes()) - } - - // finally, convey unknown fields into the given message by letting it unmarshal them - // (this will append to its unknown fields if not known; if somehow the given message recognizes - // a field even though the dynamic message did not, it will get correctly unmarshalled) - if unknownTags != nil && len(m.unknownFields) > 0 { - var b codec.Buffer - _ = m.marshalUnknownFields(&b) - _ = proto.UnmarshalMerge(b.Bytes(), pm) - } - - return nil -} - -func canConvert(src reflect.Value, target reflect.Type) bool { - if src.Kind() == reflect.Interface { - src = reflect.ValueOf(src.Interface()) - } - srcType := src.Type() - // we allow convertible types instead of requiring exact types so that calling - // code can, for example, assign an enum constant to an enum field. In that case, - // one type is the enum type (a sub-type of int32) and the other may be the int32 - // type. So we automatically do the conversion in that case. - if srcType.ConvertibleTo(target) { - return true - } else if target.Kind() == reflect.Ptr && srcType.ConvertibleTo(target.Elem()) { - return true - } else if target.Kind() == reflect.Slice { - if srcType.Kind() != reflect.Slice { - return false - } - et := target.Elem() - for i := 0; i < src.Len(); i++ { - if !canConvert(src.Index(i), et) { - return false - } - } - return true - } else if target.Kind() == reflect.Map { - if srcType.Kind() != reflect.Map { - return false - } - return canConvertMap(src, target) - } else if srcType == typeOfDynamicMessage && target.Implements(typeOfProtoMessage) { - z := reflect.Zero(target).Interface() - msgType := proto.MessageName(z.(proto.Message)) - return msgType == src.Interface().(*Message).GetMessageDescriptor().GetFullyQualifiedName() - } else { - return false - } -} - -func mergeVal(src, target reflect.Value, deterministic bool) error { - if src.Kind() == reflect.Interface && !src.IsNil() { - src = src.Elem() - } - srcType := src.Type() - targetType := target.Type() - if srcType.ConvertibleTo(targetType) { - if targetType.Implements(typeOfProtoMessage) && !target.IsNil() { - Merge(target.Interface().(proto.Message), src.Convert(targetType).Interface().(proto.Message)) - } else { - target.Set(src.Convert(targetType)) - } - } else if targetType.Kind() == reflect.Ptr && srcType.ConvertibleTo(targetType.Elem()) { - if !src.CanAddr() { - target.Set(reflect.New(targetType.Elem())) - target.Elem().Set(src.Convert(targetType.Elem())) - } else { - target.Set(src.Addr().Convert(targetType)) - } - } else if targetType.Kind() == reflect.Slice { - l := target.Len() - newL := l + src.Len() - if target.Cap() < newL { - // expand capacity of the slice and copy - newSl := reflect.MakeSlice(targetType, newL, newL) - for i := 0; i < target.Len(); i++ { - newSl.Index(i).Set(target.Index(i)) - } - target.Set(newSl) - } else { - target.SetLen(newL) - } - for i := 0; i < src.Len(); i++ { - dest := target.Index(l + i) - if dest.Kind() == reflect.Ptr { - dest.Set(reflect.New(dest.Type().Elem())) - } - if err := mergeVal(src.Index(i), dest, deterministic); err != nil { - return err - } - } - } else if targetType.Kind() == reflect.Map { - return mergeMapVal(src, target, targetType, deterministic) - } else if srcType == typeOfDynamicMessage && targetType.Implements(typeOfProtoMessage) { - dm := src.Interface().(*Message) - if target.IsNil() { - target.Set(reflect.New(targetType.Elem())) - } - m := target.Interface().(proto.Message) - if err := dm.mergeInto(m, deterministic); err != nil { - return err - } - } else { - return fmt.Errorf("cannot convert %v to %v", srcType, targetType) - } - return nil -} - -func (m *Message) mergeFrom(pm proto.Message) error { - if dm, ok := pm.(*Message); ok { - // if given message is also a dynamic message, we merge differently - for tag, v := range dm.values { - fd := m.FindFieldDescriptor(tag) - if fd == nil { - fd = dm.FindFieldDescriptor(tag) - } - if err := mergeField(m, fd, v); err != nil { - return err - } - } - return nil - } - - pmrv := reflect.ValueOf(pm) - if pmrv.IsNil() { - // nil is an empty message, so nothing to do - return nil - } - - // check that we can successfully do the merge - src := pmrv.Elem() - values := map[*desc.FieldDescriptor]interface{}{} - props := proto.GetProperties(reflect.TypeOf(pm).Elem()) - if props == nil { - return fmt.Errorf("could not determine message properties to merge for %v", reflect.TypeOf(pm).Elem()) - } - - // regular fields - for _, prop := range props.Prop { - if prop.Tag == 0 { - continue // one-of or special field (such as XXX_unrecognized, etc.) - } - fd := m.FindFieldDescriptor(int32(prop.Tag)) - if fd == nil { - // Our descriptor has different fields than this message object. So - // try to reflect on the message object's fields. - md, err := desc.LoadMessageDescriptorForMessage(pm) - if err != nil { - return err - } - fd = md.FindFieldByNumber(int32(prop.Tag)) - if fd == nil { - return fmt.Errorf("message descriptor %q did not contain field for tag %d (%q)", md.GetFullyQualifiedName(), prop.Tag, prop.Name) - } - } - rv := src.FieldByName(prop.Name) - if (rv.Kind() == reflect.Ptr || rv.Kind() == reflect.Slice) && rv.IsNil() { - continue - } - if v, err := validFieldValueForRv(fd, rv); err != nil { - return err - } else { - values[fd] = v - } - } - - // one-of fields - for _, oop := range props.OneofTypes { - oov := src.Field(oop.Field).Elem() - if !oov.IsValid() || oov.Type() != oop.Type { - // this field is unset (in other words, one-of message field is not currently set to this option) - continue - } - prop := oop.Prop - rv := oov.Elem().FieldByName(prop.Name) - fd := m.FindFieldDescriptor(int32(prop.Tag)) - if fd == nil { - // Our descriptor has different fields than this message object. So - // try to reflect on the message object's fields. - md, err := desc.LoadMessageDescriptorForMessage(pm) - if err != nil { - return err - } - fd = md.FindFieldByNumber(int32(prop.Tag)) - if fd == nil { - return fmt.Errorf("message descriptor %q did not contain field for tag %d (%q in one-of %q)", md.GetFullyQualifiedName(), prop.Tag, prop.Name, src.Type().Field(oop.Field).Name) - } - } - if v, err := validFieldValueForRv(fd, rv); err != nil { - return err - } else { - values[fd] = v - } - } - - // extension fields - rexts, _ := proto.ExtensionDescs(pm) - for _, ed := range rexts { - v, _ := proto.GetExtension(pm, ed) - if v == nil { - continue - } - if ed.ExtensionType == nil { - // unrecognized extension: we'll handle that below when we - // handle other unrecognized fields - continue - } - fd := m.er.FindExtension(m.md.GetFullyQualifiedName(), ed.Field) - if fd == nil { - var err error - if fd, err = desc.LoadFieldDescriptorForExtension(ed); err != nil { - return err - } - } - if v, err := validFieldValue(fd, v); err != nil { - return err - } else { - values[fd] = v - } - } - - // With API v2, it is possible that the new protoreflect interfaces - // were used to store an extension, which means it can't be returned - // by proto.ExtensionDescs and it's also not in the unrecognized data. - // So we have a separate loop to trawl through it... - var err error - proto.MessageReflect(pm).Range(func(fld protoreflect.FieldDescriptor, val protoreflect.Value) bool { - if !fld.IsExtension() { - // normal field... we already got it above - return true - } - xt := fld.(protoreflect.ExtensionTypeDescriptor) - if _, ok := xt.Type().(*proto.ExtensionDesc); ok { - // known extension... we already got it above - return true - } - var fd *desc.FieldDescriptor - fd, err = desc.WrapField(fld) - if err != nil { - return false - } - v := convertProtoReflectValue(val) - if v, err = validFieldValue(fd, v); err != nil { - return false - } - values[fd] = v - return true - }) - if err != nil { - return err - } - - // unrecognized extensions fields: - // In API v2 of proto, some extensions may NEITHER be included in ExtensionDescs - // above NOR included in unrecognized fields below. These are extensions that use - // a custom extension type (not a generated one -- i.e. not a linked in extension). - mr := proto.MessageReflect(pm) - var extBytes []byte - var retErr error - mr.Range(func(fld protoreflect.FieldDescriptor, val protoreflect.Value) bool { - if !fld.IsExtension() { - // normal field, already processed above - return true - } - if extd, ok := fld.(protoreflect.ExtensionTypeDescriptor); ok { - if _, ok := extd.Type().(*proto.ExtensionDesc); ok { - // normal known extension, already processed above - return true - } - } - - // marshal the extension to bytes and then handle as unknown field below - mr.New() - mr.Set(fld, val) - extBytes, retErr = protov2.MarshalOptions{}.MarshalAppend(extBytes, mr.Interface()) - return retErr == nil - }) - if retErr != nil { - return retErr - } - - // now actually perform the merge - for fd, v := range values { - if err := mergeField(m, fd, v); err != nil { - return err - } - } - - if len(extBytes) > 0 { - // treating unrecognized extensions like unknown fields: best-effort - // ignore any error returned: pulling in unknown fields is best-effort - _ = m.UnmarshalMerge(extBytes) - } - - data := internal.GetUnrecognized(pm) - if len(data) > 0 { - // ignore any error returned: pulling in unknown fields is best-effort - _ = m.UnmarshalMerge(data) - } - - return nil -} - -func convertProtoReflectValue(v protoreflect.Value) interface{} { - val := v.Interface() - switch val := val.(type) { - case protoreflect.Message: - return val.Interface() - case protoreflect.Map: - mp := make(map[interface{}]interface{}, val.Len()) - val.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool { - mp[convertProtoReflectValue(k.Value())] = convertProtoReflectValue(v) - return true - }) - return mp - case protoreflect.List: - sl := make([]interface{}, val.Len()) - for i := 0; i < val.Len(); i++ { - sl[i] = convertProtoReflectValue(val.Get(i)) - } - return sl - case protoreflect.EnumNumber: - return int32(val) - default: - return val - } -} - -// Validate checks that all required fields are present. It returns an error if any are absent. -func (m *Message) Validate() error { - missingFields := m.findMissingFields() - if len(missingFields) == 0 { - return nil - } - return fmt.Errorf("some required fields missing: %v", strings.Join(missingFields, ", ")) -} - -func (m *Message) findMissingFields() []string { - if m.md.IsProto3() { - // proto3 does not allow required fields - return nil - } - var missingFields []string - for _, fd := range m.md.GetFields() { - if fd.IsRequired() { - if _, ok := m.values[fd.GetNumber()]; !ok { - missingFields = append(missingFields, fd.GetName()) - } - } - } - return missingFields -} - -// ValidateRecursive checks that all required fields are present and also -// recursively validates all fields who are also messages. It returns an error -// if any required fields, in this message or nested within, are absent. -func (m *Message) ValidateRecursive() error { - return m.validateRecursive("") -} - -func (m *Message) validateRecursive(prefix string) error { - if missingFields := m.findMissingFields(); len(missingFields) > 0 { - for i := range missingFields { - missingFields[i] = fmt.Sprintf("%s%s", prefix, missingFields[i]) - } - return fmt.Errorf("some required fields missing: %v", strings.Join(missingFields, ", ")) - } - - for tag, fld := range m.values { - fd := m.FindFieldDescriptor(tag) - var chprefix string - var md *desc.MessageDescriptor - checkMsg := func(pm proto.Message) error { - var dm *Message - if d, ok := pm.(*Message); ok { - dm = d - } else if pm != nil { - dm = m.mf.NewDynamicMessage(md) - if err := dm.ConvertFrom(pm); err != nil { - return nil - } - } - if dm == nil { - return nil - } - if err := dm.validateRecursive(chprefix); err != nil { - return err - } - return nil - } - isMap := fd.IsMap() - if isMap && fd.GetMapValueType().GetMessageType() != nil { - md = fd.GetMapValueType().GetMessageType() - mp := fld.(map[interface{}]interface{}) - for k, v := range mp { - chprefix = fmt.Sprintf("%s%s[%v].", prefix, getName(fd), k) - if err := checkMsg(v.(proto.Message)); err != nil { - return err - } - } - } else if !isMap && fd.GetMessageType() != nil { - md = fd.GetMessageType() - if fd.IsRepeated() { - sl := fld.([]interface{}) - for i, v := range sl { - chprefix = fmt.Sprintf("%s%s[%d].", prefix, getName(fd), i) - if err := checkMsg(v.(proto.Message)); err != nil { - return err - } - } - } else { - chprefix = fmt.Sprintf("%s%s.", prefix, getName(fd)) - if err := checkMsg(fld.(proto.Message)); err != nil { - return err - } - } - } - } - - return nil -} - -func getName(fd *desc.FieldDescriptor) string { - if fd.IsExtension() { - return fmt.Sprintf("(%s)", fd.GetFullyQualifiedName()) - } else { - return fd.GetName() - } -} - -// knownFieldTags return tags of present and recognized fields, in sorted order. -func (m *Message) knownFieldTags() []int { - if len(m.values) == 0 { - return []int(nil) - } - - keys := make([]int, len(m.values)) - i := 0 - for k := range m.values { - keys[i] = int(k) - i++ - } - - sort.Ints(keys) - return keys -} - -// allKnownFieldTags return tags of present and recognized fields, including -// those that are unset, in sorted order. This only includes extensions that are -// present. Known but not-present extensions are not included in the returned -// set of tags. -func (m *Message) allKnownFieldTags() []int { - fds := m.md.GetFields() - keys := make([]int, 0, len(fds)+len(m.extraFields)) - - for k := range m.values { - keys = append(keys, int(k)) - } - - // also include known fields that are not present - for _, fd := range fds { - if _, ok := m.values[fd.GetNumber()]; !ok { - keys = append(keys, int(fd.GetNumber())) - } - } - for _, fd := range m.extraFields { - if !fd.IsExtension() { // skip extensions that are not present - if _, ok := m.values[fd.GetNumber()]; !ok { - keys = append(keys, int(fd.GetNumber())) - } - } - } - - sort.Ints(keys) - return keys -} - -// unknownFieldTags return tags of present but unrecognized fields, in sorted order. -func (m *Message) unknownFieldTags() []int { - if len(m.unknownFields) == 0 { - return []int(nil) - } - keys := make([]int, len(m.unknownFields)) - i := 0 - for k := range m.unknownFields { - keys[i] = int(k) - i++ - } - sort.Ints(keys) - return keys -} diff --git a/vendor/github.com/jhump/protoreflect/dynamic/equal.go b/vendor/github.com/jhump/protoreflect/dynamic/equal.go deleted file mode 100644 index e44c6c53..00000000 --- a/vendor/github.com/jhump/protoreflect/dynamic/equal.go +++ /dev/null @@ -1,157 +0,0 @@ -package dynamic - -import ( - "bytes" - "reflect" - - "github.com/golang/protobuf/proto" - - "github.com/jhump/protoreflect/desc" -) - -// Equal returns true if the given two dynamic messages are equal. Two messages are equal when they -// have the same message type and same fields set to equal values. For proto3 messages, fields set -// to their zero value are considered unset. -func Equal(a, b *Message) bool { - if a == b { - return true - } - if (a == nil) != (b == nil) { - return false - } - if a.md.GetFullyQualifiedName() != b.md.GetFullyQualifiedName() { - return false - } - if len(a.values) != len(b.values) { - return false - } - if len(a.unknownFields) != len(b.unknownFields) { - return false - } - for tag, aval := range a.values { - bval, ok := b.values[tag] - if !ok { - return false - } - if !fieldsEqual(aval, bval) { - return false - } - } - for tag, au := range a.unknownFields { - bu, ok := b.unknownFields[tag] - if !ok { - return false - } - if len(au) != len(bu) { - return false - } - for i, aval := range au { - bval := bu[i] - if aval.Encoding != bval.Encoding { - return false - } - if aval.Encoding == proto.WireBytes || aval.Encoding == proto.WireStartGroup { - if !bytes.Equal(aval.Contents, bval.Contents) { - return false - } - } else if aval.Value != bval.Value { - return false - } - } - } - // all checks pass! - return true -} - -func fieldsEqual(aval, bval interface{}) bool { - arv := reflect.ValueOf(aval) - brv := reflect.ValueOf(bval) - if arv.Type() != brv.Type() { - // it is possible that one is a dynamic message and one is not - apm, ok := aval.(proto.Message) - if !ok { - return false - } - bpm, ok := bval.(proto.Message) - if !ok { - return false - } - return MessagesEqual(apm, bpm) - - } else { - switch arv.Kind() { - case reflect.Ptr: - apm, ok := aval.(proto.Message) - if !ok { - // Don't know how to compare pointer values that aren't messages! - // Maybe this should panic? - return false - } - bpm := bval.(proto.Message) // we know it will succeed because we know a and b have same type - return MessagesEqual(apm, bpm) - - case reflect.Map: - return mapsEqual(arv, brv) - - case reflect.Slice: - if arv.Type() == typeOfBytes { - return bytes.Equal(aval.([]byte), bval.([]byte)) - } else { - return slicesEqual(arv, brv) - } - - default: - return aval == bval - } - } -} - -func slicesEqual(a, b reflect.Value) bool { - if a.Len() != b.Len() { - return false - } - for i := 0; i < a.Len(); i++ { - ai := a.Index(i) - bi := b.Index(i) - if !fieldsEqual(ai.Interface(), bi.Interface()) { - return false - } - } - return true -} - -// MessagesEqual returns true if the given two messages are equal. Use this instead of proto.Equal -// when one or both of the messages might be a dynamic message. -func MessagesEqual(a, b proto.Message) bool { - da, aok := a.(*Message) - db, bok := b.(*Message) - // Both dynamic messages - if aok && bok { - return Equal(da, db) - } - // Neither dynamic messages - if !aok && !bok { - return proto.Equal(a, b) - } - // Mixed - if bok { - // we want a to be the dynamic one - b, da = a, db - } - - // Instead of panic'ing below if we have a nil dynamic message, check - // now and return false if the input message is not also nil. - if da == nil { - return isNil(b) - } - - md, err := desc.LoadMessageDescriptorForMessage(b) - if err != nil { - return false - } - db = NewMessageWithMessageFactory(md, da.mf) - if db.ConvertFrom(b) != nil { - return false - } - return Equal(da, db) -} diff --git a/vendor/github.com/jhump/protoreflect/dynamic/extension.go b/vendor/github.com/jhump/protoreflect/dynamic/extension.go deleted file mode 100644 index 1d381610..00000000 --- a/vendor/github.com/jhump/protoreflect/dynamic/extension.go +++ /dev/null @@ -1,46 +0,0 @@ -package dynamic - -import ( - "fmt" - - "github.com/golang/protobuf/proto" - - "github.com/jhump/protoreflect/codec" - "github.com/jhump/protoreflect/desc" -) - -// SetExtension sets the given extension value. If the given message is not a -// dynamic message, the given extension may not be recognized (or may differ -// from the compiled and linked in version of the extension. So in that case, -// this function will serialize the given value to bytes and then use -// proto.SetRawExtension to set the value. -func SetExtension(msg proto.Message, extd *desc.FieldDescriptor, val interface{}) error { - if !extd.IsExtension() { - return fmt.Errorf("given field %s is not an extension", extd.GetFullyQualifiedName()) - } - - if dm, ok := msg.(*Message); ok { - return dm.TrySetField(extd, val) - } - - md, err := desc.LoadMessageDescriptorForMessage(msg) - if err != nil { - return err - } - if err := checkField(extd, md); err != nil { - return err - } - - val, err = validFieldValue(extd, val) - if err != nil { - return err - } - - var b codec.Buffer - b.SetDeterministic(defaultDeterminism) - if err := b.EncodeFieldValue(extd, val); err != nil { - return err - } - proto.SetRawExtension(msg, extd.GetNumber(), b.Bytes()) - return nil -} diff --git a/vendor/github.com/jhump/protoreflect/dynamic/extension_registry.go b/vendor/github.com/jhump/protoreflect/dynamic/extension_registry.go deleted file mode 100644 index 68768278..00000000 --- a/vendor/github.com/jhump/protoreflect/dynamic/extension_registry.go +++ /dev/null @@ -1,241 +0,0 @@ -package dynamic - -import ( - "fmt" - "reflect" - "sync" - - "github.com/golang/protobuf/proto" - - "github.com/jhump/protoreflect/desc" -) - -// ExtensionRegistry is a registry of known extension fields. This is used to parse -// extension fields encountered when de-serializing a dynamic message. -type ExtensionRegistry struct { - includeDefault bool - mu sync.RWMutex - exts map[string]map[int32]*desc.FieldDescriptor -} - -// NewExtensionRegistryWithDefaults is a registry that includes all "default" extensions, -// which are those that are statically linked into the current program (e.g. registered by -// protoc-generated code via proto.RegisterExtension). Extensions explicitly added to the -// registry will override any default extensions that are for the same extendee and have the -// same tag number and/or name. -func NewExtensionRegistryWithDefaults() *ExtensionRegistry { - return &ExtensionRegistry{includeDefault: true} -} - -// AddExtensionDesc adds the given extensions to the registry. -func (r *ExtensionRegistry) AddExtensionDesc(exts ...*proto.ExtensionDesc) error { - flds := make([]*desc.FieldDescriptor, len(exts)) - for i, ext := range exts { - fd, err := desc.LoadFieldDescriptorForExtension(ext) - if err != nil { - return err - } - flds[i] = fd - } - r.mu.Lock() - defer r.mu.Unlock() - if r.exts == nil { - r.exts = map[string]map[int32]*desc.FieldDescriptor{} - } - for _, fd := range flds { - r.putExtensionLocked(fd) - } - return nil -} - -// AddExtension adds the given extensions to the registry. The given extensions -// will overwrite any previously added extensions that are for the same extendee -// message and same extension tag number. -func (r *ExtensionRegistry) AddExtension(exts ...*desc.FieldDescriptor) error { - for _, ext := range exts { - if !ext.IsExtension() { - return fmt.Errorf("given field is not an extension: %s", ext.GetFullyQualifiedName()) - } - } - r.mu.Lock() - defer r.mu.Unlock() - if r.exts == nil { - r.exts = map[string]map[int32]*desc.FieldDescriptor{} - } - for _, ext := range exts { - r.putExtensionLocked(ext) - } - return nil -} - -// AddExtensionsFromFile adds to the registry all extension fields defined in the given file descriptor. -func (r *ExtensionRegistry) AddExtensionsFromFile(fd *desc.FileDescriptor) { - r.mu.Lock() - defer r.mu.Unlock() - r.addExtensionsFromFileLocked(fd, false, nil) -} - -// AddExtensionsFromFileRecursively adds to the registry all extension fields defined in the give file -// descriptor and also recursively adds all extensions defined in that file's dependencies. This adds -// extensions from the entire transitive closure for the given file. -func (r *ExtensionRegistry) AddExtensionsFromFileRecursively(fd *desc.FileDescriptor) { - r.mu.Lock() - defer r.mu.Unlock() - already := map[*desc.FileDescriptor]struct{}{} - r.addExtensionsFromFileLocked(fd, true, already) -} - -func (r *ExtensionRegistry) addExtensionsFromFileLocked(fd *desc.FileDescriptor, recursive bool, alreadySeen map[*desc.FileDescriptor]struct{}) { - if _, ok := alreadySeen[fd]; ok { - return - } - - if r.exts == nil { - r.exts = map[string]map[int32]*desc.FieldDescriptor{} - } - for _, ext := range fd.GetExtensions() { - r.putExtensionLocked(ext) - } - for _, msg := range fd.GetMessageTypes() { - r.addExtensionsFromMessageLocked(msg) - } - - if recursive { - alreadySeen[fd] = struct{}{} - for _, dep := range fd.GetDependencies() { - r.addExtensionsFromFileLocked(dep, recursive, alreadySeen) - } - } -} - -func (r *ExtensionRegistry) addExtensionsFromMessageLocked(md *desc.MessageDescriptor) { - for _, ext := range md.GetNestedExtensions() { - r.putExtensionLocked(ext) - } - for _, msg := range md.GetNestedMessageTypes() { - r.addExtensionsFromMessageLocked(msg) - } -} - -func (r *ExtensionRegistry) putExtensionLocked(fd *desc.FieldDescriptor) { - msgName := fd.GetOwner().GetFullyQualifiedName() - m := r.exts[msgName] - if m == nil { - m = map[int32]*desc.FieldDescriptor{} - r.exts[msgName] = m - } - m[fd.GetNumber()] = fd -} - -// FindExtension queries for the extension field with the given extendee name (must be a fully-qualified -// message name) and tag number. If no extension is known, nil is returned. -func (r *ExtensionRegistry) FindExtension(messageName string, tagNumber int32) *desc.FieldDescriptor { - if r == nil { - return nil - } - r.mu.RLock() - defer r.mu.RUnlock() - fd := r.exts[messageName][tagNumber] - if fd == nil && r.includeDefault { - ext := getDefaultExtensions(messageName)[tagNumber] - if ext != nil { - fd, _ = desc.LoadFieldDescriptorForExtension(ext) - } - } - return fd -} - -// FindExtensionByName queries for the extension field with the given extendee name (must be a fully-qualified -// message name) and field name (must also be a fully-qualified extension name). If no extension is known, nil -// is returned. -func (r *ExtensionRegistry) FindExtensionByName(messageName string, fieldName string) *desc.FieldDescriptor { - if r == nil { - return nil - } - r.mu.RLock() - defer r.mu.RUnlock() - for _, fd := range r.exts[messageName] { - if fd.GetFullyQualifiedName() == fieldName { - return fd - } - } - if r.includeDefault { - for _, ext := range getDefaultExtensions(messageName) { - fd, _ := desc.LoadFieldDescriptorForExtension(ext) - if fd.GetFullyQualifiedName() == fieldName { - return fd - } - } - } - return nil -} - -// FindExtensionByJSONName queries for the extension field with the given extendee name (must be a fully-qualified -// message name) and JSON field name (must also be a fully-qualified name). If no extension is known, nil is returned. -// The fully-qualified JSON name is the same as the extension's normal fully-qualified name except that the last -// component uses the field's JSON name (if present). -func (r *ExtensionRegistry) FindExtensionByJSONName(messageName string, fieldName string) *desc.FieldDescriptor { - if r == nil { - return nil - } - r.mu.RLock() - defer r.mu.RUnlock() - for _, fd := range r.exts[messageName] { - if fd.GetFullyQualifiedJSONName() == fieldName { - return fd - } - } - if r.includeDefault { - for _, ext := range getDefaultExtensions(messageName) { - fd, _ := desc.LoadFieldDescriptorForExtension(ext) - if fd.GetFullyQualifiedJSONName() == fieldName { - return fd - } - } - } - return nil -} - -func getDefaultExtensions(messageName string) map[int32]*proto.ExtensionDesc { - t := proto.MessageType(messageName) - if t != nil { - msg := reflect.Zero(t).Interface().(proto.Message) - return proto.RegisteredExtensions(msg) - } - return nil -} - -// AllExtensionsForType returns all known extension fields for the given extendee name (must be a -// fully-qualified message name). -func (r *ExtensionRegistry) AllExtensionsForType(messageName string) []*desc.FieldDescriptor { - if r == nil { - return []*desc.FieldDescriptor(nil) - } - r.mu.RLock() - defer r.mu.RUnlock() - flds := r.exts[messageName] - var ret []*desc.FieldDescriptor - if r.includeDefault { - exts := getDefaultExtensions(messageName) - if len(exts) > 0 || len(flds) > 0 { - ret = make([]*desc.FieldDescriptor, 0, len(exts)+len(flds)) - } - for tag, ext := range exts { - if _, ok := flds[tag]; ok { - // skip default extension and use the one explicitly registered instead - continue - } - fd, _ := desc.LoadFieldDescriptorForExtension(ext) - if fd != nil { - ret = append(ret, fd) - } - } - } else if len(flds) > 0 { - ret = make([]*desc.FieldDescriptor, 0, len(flds)) - } - - for _, ext := range flds { - ret = append(ret, ext) - } - return ret -} diff --git a/vendor/github.com/jhump/protoreflect/dynamic/indent.go b/vendor/github.com/jhump/protoreflect/dynamic/indent.go deleted file mode 100644 index bd7fcaa5..00000000 --- a/vendor/github.com/jhump/protoreflect/dynamic/indent.go +++ /dev/null @@ -1,76 +0,0 @@ -package dynamic - -import "bytes" - -type indentBuffer struct { - bytes.Buffer - indent string - indentCount int - comma bool -} - -func (b *indentBuffer) start() error { - if b.indentCount >= 0 { - b.indentCount++ - return b.newLine(false) - } - return nil -} - -func (b *indentBuffer) sep() error { - if b.indentCount >= 0 { - _, err := b.WriteString(": ") - return err - } else { - return b.WriteByte(':') - } -} - -func (b *indentBuffer) end() error { - if b.indentCount >= 0 { - b.indentCount-- - return b.newLine(false) - } - return nil -} - -func (b *indentBuffer) maybeNext(first *bool) error { - if *first { - *first = false - return nil - } else { - return b.next() - } -} - -func (b *indentBuffer) next() error { - if b.indentCount >= 0 { - return b.newLine(b.comma) - } else if b.comma { - return b.WriteByte(',') - } else { - return b.WriteByte(' ') - } -} - -func (b *indentBuffer) newLine(comma bool) error { - if comma { - err := b.WriteByte(',') - if err != nil { - return err - } - } - - err := b.WriteByte('\n') - if err != nil { - return err - } - - for i := 0; i < b.indentCount; i++ { - _, err := b.WriteString(b.indent) - if err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/jhump/protoreflect/dynamic/json.go b/vendor/github.com/jhump/protoreflect/dynamic/json.go deleted file mode 100644 index 9081965f..00000000 --- a/vendor/github.com/jhump/protoreflect/dynamic/json.go +++ /dev/null @@ -1,1256 +0,0 @@ -package dynamic - -// JSON marshalling and unmarshalling for dynamic messages - -import ( - "bytes" - "encoding/base64" - "encoding/json" - "fmt" - "io" - "io/ioutil" - "math" - "reflect" - "sort" - "strconv" - "strings" - - "github.com/golang/protobuf/jsonpb" - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/types/descriptorpb" - // link in the well-known-types that have a special JSON format - _ "google.golang.org/protobuf/types/known/anypb" - _ "google.golang.org/protobuf/types/known/durationpb" - _ "google.golang.org/protobuf/types/known/emptypb" - _ "google.golang.org/protobuf/types/known/structpb" - _ "google.golang.org/protobuf/types/known/timestamppb" - _ "google.golang.org/protobuf/types/known/wrapperspb" - - "github.com/jhump/protoreflect/desc" -) - -var wellKnownTypeNames = map[string]struct{}{ - "google.protobuf.Any": {}, - "google.protobuf.Empty": {}, - "google.protobuf.Duration": {}, - "google.protobuf.Timestamp": {}, - // struct.proto - "google.protobuf.Struct": {}, - "google.protobuf.Value": {}, - "google.protobuf.ListValue": {}, - // wrappers.proto - "google.protobuf.DoubleValue": {}, - "google.protobuf.FloatValue": {}, - "google.protobuf.Int64Value": {}, - "google.protobuf.UInt64Value": {}, - "google.protobuf.Int32Value": {}, - "google.protobuf.UInt32Value": {}, - "google.protobuf.BoolValue": {}, - "google.protobuf.StringValue": {}, - "google.protobuf.BytesValue": {}, -} - -// MarshalJSON serializes this message to bytes in JSON format, returning an -// error if the operation fails. The resulting bytes will be a valid UTF8 -// string. -// -// This method uses a compact form: no newlines, and spaces between fields and -// between field identifiers and values are elided. -// -// This method is convenient shorthand for invoking MarshalJSONPB with a default -// (zero value) marshaler: -// -// m.MarshalJSONPB(&jsonpb.Marshaler{}) -// -// So enums are serialized using enum value name strings, and values that are -// not present (including those with default/zero value for messages defined in -// "proto3" syntax) are omitted. -func (m *Message) MarshalJSON() ([]byte, error) { - return m.MarshalJSONPB(&jsonpb.Marshaler{}) -} - -// MarshalJSONIndent serializes this message to bytes in JSON format, returning -// an error if the operation fails. The resulting bytes will be a valid UTF8 -// string. -// -// This method uses a "pretty-printed" form, with each field on its own line and -// spaces between field identifiers and values. Indentation of two spaces is -// used. -// -// This method is convenient shorthand for invoking MarshalJSONPB with a default -// (zero value) marshaler: -// -// m.MarshalJSONPB(&jsonpb.Marshaler{Indent: " "}) -// -// So enums are serialized using enum value name strings, and values that are -// not present (including those with default/zero value for messages defined in -// "proto3" syntax) are omitted. -func (m *Message) MarshalJSONIndent() ([]byte, error) { - return m.MarshalJSONPB(&jsonpb.Marshaler{Indent: " "}) -} - -// MarshalJSONPB serializes this message to bytes in JSON format, returning an -// error if the operation fails. The resulting bytes will be a valid UTF8 -// string. The given marshaler is used to convey options used during marshaling. -// -// If this message contains nested messages that are generated message types (as -// opposed to dynamic messages), the given marshaler is used to marshal it. -// -// When marshaling any nested messages, any jsonpb.AnyResolver configured in the -// given marshaler is augmented with knowledge of message types known to this -// message's descriptor (and its enclosing file and set of transitive -// dependencies). -func (m *Message) MarshalJSONPB(opts *jsonpb.Marshaler) ([]byte, error) { - var b indentBuffer - b.indent = opts.Indent - if len(opts.Indent) == 0 { - b.indentCount = -1 - } - b.comma = true - if err := m.marshalJSON(&b, opts); err != nil { - return nil, err - } - return b.Bytes(), nil -} - -func (m *Message) marshalJSON(b *indentBuffer, opts *jsonpb.Marshaler) error { - if m == nil { - _, err := b.WriteString("null") - return err - } - if r, changed := wrapResolver(opts.AnyResolver, m.mf, m.md.GetFile()); changed { - newOpts := *opts - newOpts.AnyResolver = r - opts = &newOpts - } - - if ok, err := marshalWellKnownType(m, b, opts); ok { - return err - } - - err := b.WriteByte('{') - if err != nil { - return err - } - err = b.start() - if err != nil { - return err - } - - var tags []int - if opts.EmitDefaults { - tags = m.allKnownFieldTags() - } else { - tags = m.knownFieldTags() - } - - first := true - - for _, tag := range tags { - itag := int32(tag) - fd := m.FindFieldDescriptor(itag) - - v, ok := m.values[itag] - if !ok { - if fd.GetOneOf() != nil { - // don't print defaults for fields in a oneof - continue - } - v = fd.GetDefaultValue() - } - - err := b.maybeNext(&first) - if err != nil { - return err - } - err = marshalKnownFieldJSON(b, fd, v, opts) - if err != nil { - return err - } - } - - err = b.end() - if err != nil { - return err - } - err = b.WriteByte('}') - if err != nil { - return err - } - - return nil -} - -func marshalWellKnownType(m *Message, b *indentBuffer, opts *jsonpb.Marshaler) (bool, error) { - fqn := m.md.GetFullyQualifiedName() - if _, ok := wellKnownTypeNames[fqn]; !ok { - return false, nil - } - - msgType := proto.MessageType(fqn) - if msgType == nil { - // wtf? - panic(fmt.Sprintf("could not find registered message type for %q", fqn)) - } - - // convert dynamic message to well-known type and let jsonpb marshal it - msg := reflect.New(msgType.Elem()).Interface().(proto.Message) - if err := m.MergeInto(msg); err != nil { - return true, err - } - return true, opts.Marshal(b, msg) -} - -func marshalKnownFieldJSON(b *indentBuffer, fd *desc.FieldDescriptor, v interface{}, opts *jsonpb.Marshaler) error { - var jsonName string - if opts.OrigName { - jsonName = fd.GetName() - } else { - jsonName = fd.AsFieldDescriptorProto().GetJsonName() - if jsonName == "" { - jsonName = fd.GetName() - } - } - if fd.IsExtension() { - var scope string - switch parent := fd.GetParent().(type) { - case *desc.FileDescriptor: - scope = parent.GetPackage() - default: - scope = parent.GetFullyQualifiedName() - } - if scope == "" { - jsonName = fmt.Sprintf("[%s]", jsonName) - } else { - jsonName = fmt.Sprintf("[%s.%s]", scope, jsonName) - } - } - err := writeJsonString(b, jsonName) - if err != nil { - return err - } - err = b.sep() - if err != nil { - return err - } - - if isNil(v) { - _, err := b.WriteString("null") - return err - } - - if fd.IsMap() { - err = b.WriteByte('{') - if err != nil { - return err - } - err = b.start() - if err != nil { - return err - } - - md := fd.GetMessageType() - vfd := md.FindFieldByNumber(2) - - mp := v.(map[interface{}]interface{}) - keys := make([]interface{}, 0, len(mp)) - for k := range mp { - keys = append(keys, k) - } - sort.Sort(sortable(keys)) - first := true - for _, mk := range keys { - mv := mp[mk] - err := b.maybeNext(&first) - if err != nil { - return err - } - - err = marshalKnownFieldMapEntryJSON(b, mk, vfd, mv, opts) - if err != nil { - return err - } - } - - err = b.end() - if err != nil { - return err - } - return b.WriteByte('}') - - } else if fd.IsRepeated() { - err = b.WriteByte('[') - if err != nil { - return err - } - err = b.start() - if err != nil { - return err - } - - sl := v.([]interface{}) - first := true - for _, slv := range sl { - err := b.maybeNext(&first) - if err != nil { - return err - } - err = marshalKnownFieldValueJSON(b, fd, slv, opts) - if err != nil { - return err - } - } - - err = b.end() - if err != nil { - return err - } - return b.WriteByte(']') - - } else { - return marshalKnownFieldValueJSON(b, fd, v, opts) - } -} - -// sortable is used to sort map keys. Values will be integers (int32, int64, uint32, and uint64), -// bools, or strings. -type sortable []interface{} - -func (s sortable) Len() int { - return len(s) -} - -func (s sortable) Less(i, j int) bool { - vi := s[i] - vj := s[j] - switch reflect.TypeOf(vi).Kind() { - case reflect.Int32: - return vi.(int32) < vj.(int32) - case reflect.Int64: - return vi.(int64) < vj.(int64) - case reflect.Uint32: - return vi.(uint32) < vj.(uint32) - case reflect.Uint64: - return vi.(uint64) < vj.(uint64) - case reflect.String: - return vi.(string) < vj.(string) - case reflect.Bool: - return !vi.(bool) && vj.(bool) - default: - panic(fmt.Sprintf("cannot compare keys of type %v", reflect.TypeOf(vi))) - } -} - -func (s sortable) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -func isNil(v interface{}) bool { - if v == nil { - return true - } - rv := reflect.ValueOf(v) - return rv.Kind() == reflect.Ptr && rv.IsNil() -} - -func marshalKnownFieldMapEntryJSON(b *indentBuffer, mk interface{}, vfd *desc.FieldDescriptor, mv interface{}, opts *jsonpb.Marshaler) error { - rk := reflect.ValueOf(mk) - var strkey string - switch rk.Kind() { - case reflect.Bool: - strkey = strconv.FormatBool(rk.Bool()) - case reflect.Int32, reflect.Int64: - strkey = strconv.FormatInt(rk.Int(), 10) - case reflect.Uint32, reflect.Uint64: - strkey = strconv.FormatUint(rk.Uint(), 10) - case reflect.String: - strkey = rk.String() - default: - return fmt.Errorf("invalid map key value: %v (%v)", mk, rk.Type()) - } - err := writeJsonString(b, strkey) - if err != nil { - return err - } - err = b.sep() - if err != nil { - return err - } - return marshalKnownFieldValueJSON(b, vfd, mv, opts) -} - -func marshalKnownFieldValueJSON(b *indentBuffer, fd *desc.FieldDescriptor, v interface{}, opts *jsonpb.Marshaler) error { - rv := reflect.ValueOf(v) - switch rv.Kind() { - case reflect.Int64: - return writeJsonString(b, strconv.FormatInt(rv.Int(), 10)) - case reflect.Int32: - ed := fd.GetEnumType() - if !opts.EnumsAsInts && ed != nil { - n := int32(rv.Int()) - vd := ed.FindValueByNumber(n) - if vd == nil { - _, err := b.WriteString(strconv.FormatInt(rv.Int(), 10)) - return err - } else { - return writeJsonString(b, vd.GetName()) - } - } else { - _, err := b.WriteString(strconv.FormatInt(rv.Int(), 10)) - return err - } - case reflect.Uint64: - return writeJsonString(b, strconv.FormatUint(rv.Uint(), 10)) - case reflect.Uint32: - _, err := b.WriteString(strconv.FormatUint(rv.Uint(), 10)) - return err - case reflect.Float32, reflect.Float64: - f := rv.Float() - var str string - if math.IsNaN(f) { - str = `"NaN"` - } else if math.IsInf(f, 1) { - str = `"Infinity"` - } else if math.IsInf(f, -1) { - str = `"-Infinity"` - } else { - var bits int - if rv.Kind() == reflect.Float32 { - bits = 32 - } else { - bits = 64 - } - str = strconv.FormatFloat(rv.Float(), 'g', -1, bits) - } - _, err := b.WriteString(str) - return err - case reflect.Bool: - _, err := b.WriteString(strconv.FormatBool(rv.Bool())) - return err - case reflect.Slice: - bstr := base64.StdEncoding.EncodeToString(rv.Bytes()) - return writeJsonString(b, bstr) - case reflect.String: - return writeJsonString(b, rv.String()) - default: - // must be a message - if isNil(v) { - _, err := b.WriteString("null") - return err - } - - if dm, ok := v.(*Message); ok { - return dm.marshalJSON(b, opts) - } - - var err error - if b.indentCount <= 0 || len(b.indent) == 0 { - err = opts.Marshal(b, v.(proto.Message)) - } else { - str, err := opts.MarshalToString(v.(proto.Message)) - if err != nil { - return err - } - indent := strings.Repeat(b.indent, b.indentCount) - pos := 0 - // add indention prefix to each line - for pos < len(str) { - start := pos - nextPos := strings.Index(str[pos:], "\n") - if nextPos == -1 { - nextPos = len(str) - } else { - nextPos = pos + nextPos + 1 // include newline - } - line := str[start:nextPos] - if pos > 0 { - _, err = b.WriteString(indent) - if err != nil { - return err - } - } - _, err = b.WriteString(line) - if err != nil { - return err - } - pos = nextPos - } - } - return err - } -} - -func writeJsonString(b *indentBuffer, s string) error { - if sbytes, err := json.Marshal(s); err != nil { - return err - } else { - _, err := b.Write(sbytes) - return err - } -} - -// UnmarshalJSON de-serializes the message that is present, in JSON format, in -// the given bytes into this message. It first resets the current message. It -// returns an error if the given bytes do not contain a valid encoding of this -// message type in JSON format. -// -// This method is shorthand for invoking UnmarshalJSONPB with a default (zero -// value) unmarshaler: -// -// m.UnmarshalMergeJSONPB(&jsonpb.Unmarshaler{}, js) -// -// So unknown fields will result in an error, and no provided jsonpb.AnyResolver -// will be used when parsing google.protobuf.Any messages. -func (m *Message) UnmarshalJSON(js []byte) error { - return m.UnmarshalJSONPB(&jsonpb.Unmarshaler{}, js) -} - -// UnmarshalMergeJSON de-serializes the message that is present, in JSON format, -// in the given bytes into this message. Unlike UnmarshalJSON, it does not first -// reset the message, instead merging the data in the given bytes into the -// existing data in this message. -func (m *Message) UnmarshalMergeJSON(js []byte) error { - return m.UnmarshalMergeJSONPB(&jsonpb.Unmarshaler{}, js) -} - -// UnmarshalJSONPB de-serializes the message that is present, in JSON format, in -// the given bytes into this message. The given unmarshaler conveys options used -// when parsing the JSON. This function first resets the current message. It -// returns an error if the given bytes do not contain a valid encoding of this -// message type in JSON format. -// -// The decoding is lenient: -// 1. The JSON can refer to fields either by their JSON name or by their -// declared name. -// 2. The JSON can use either numeric values or string names for enum values. -// -// When instantiating nested messages, if this message's associated factory -// returns a generated message type (as opposed to a dynamic message), the given -// unmarshaler is used to unmarshal it. -// -// When unmarshaling any nested messages, any jsonpb.AnyResolver configured in -// the given unmarshaler is augmented with knowledge of message types known to -// this message's descriptor (and its enclosing file and set of transitive -// dependencies). -func (m *Message) UnmarshalJSONPB(opts *jsonpb.Unmarshaler, js []byte) error { - m.Reset() - if err := m.UnmarshalMergeJSONPB(opts, js); err != nil { - return err - } - return m.Validate() -} - -// UnmarshalMergeJSONPB de-serializes the message that is present, in JSON -// format, in the given bytes into this message. The given unmarshaler conveys -// options used when parsing the JSON. Unlike UnmarshalJSONPB, it does not first -// reset the message, instead merging the data in the given bytes into the -// existing data in this message. -func (m *Message) UnmarshalMergeJSONPB(opts *jsonpb.Unmarshaler, js []byte) error { - r := newJsReader(js) - err := m.unmarshalJson(r, opts) - if err != nil { - return err - } - if t, err := r.poll(); err != io.EOF { - b, _ := ioutil.ReadAll(r.unread()) - s := fmt.Sprintf("%v%s", t, string(b)) - return fmt.Errorf("superfluous data found after JSON object: %q", s) - } - return nil -} - -func unmarshalWellKnownType(m *Message, r *jsReader, opts *jsonpb.Unmarshaler) (bool, error) { - fqn := m.md.GetFullyQualifiedName() - if _, ok := wellKnownTypeNames[fqn]; !ok { - return false, nil - } - - msgType := proto.MessageType(fqn) - if msgType == nil { - // wtf? - panic(fmt.Sprintf("could not find registered message type for %q", fqn)) - } - - // extract json value from r - var js json.RawMessage - if err := json.NewDecoder(r.unread()).Decode(&js); err != nil { - return true, err - } - if err := r.skip(); err != nil { - return true, err - } - - // unmarshal into well-known type and then convert to dynamic message - msg := reflect.New(msgType.Elem()).Interface().(proto.Message) - if err := opts.Unmarshal(bytes.NewReader(js), msg); err != nil { - return true, err - } - return true, m.MergeFrom(msg) -} - -func (m *Message) unmarshalJson(r *jsReader, opts *jsonpb.Unmarshaler) error { - if r, changed := wrapResolver(opts.AnyResolver, m.mf, m.md.GetFile()); changed { - newOpts := *opts - newOpts.AnyResolver = r - opts = &newOpts - } - - if ok, err := unmarshalWellKnownType(m, r, opts); ok { - return err - } - - t, err := r.peek() - if err != nil { - return err - } - if t == nil { - // if json is simply "null" we do nothing - r.poll() - return nil - } - - if err := r.beginObject(); err != nil { - return err - } - - for r.hasNext() { - f, err := r.nextObjectKey() - if err != nil { - return err - } - fd := m.FindFieldDescriptorByJSONName(f) - if fd == nil { - if opts.AllowUnknownFields { - r.skip() - continue - } - return fmt.Errorf("message type %s has no known field named %s", m.md.GetFullyQualifiedName(), f) - } - v, err := unmarshalJsField(fd, r, m.mf, opts) - if err != nil { - return err - } - if v != nil { - if err := mergeField(m, fd, v); err != nil { - return err - } - } else if fd.GetOneOf() != nil { - // preserve explicit null for oneof fields (this is a little odd but - // mimics the behavior of jsonpb with oneofs in generated message types) - if fd.GetMessageType() != nil { - typ := m.mf.GetKnownTypeRegistry().GetKnownType(fd.GetMessageType().GetFullyQualifiedName()) - if typ != nil { - // typed nil - if typ.Kind() != reflect.Ptr { - typ = reflect.PtrTo(typ) - } - v = reflect.Zero(typ).Interface() - } else { - // can't use nil dynamic message, so we just use empty one instead - v = m.mf.NewDynamicMessage(fd.GetMessageType()) - } - if err := m.setField(fd, v); err != nil { - return err - } - } else { - // not a message... explicit null makes no sense - return fmt.Errorf("message type %s cannot set field %s to null: it is not a message type", m.md.GetFullyQualifiedName(), f) - } - } else { - m.clearField(fd) - } - } - - if err := r.endObject(); err != nil { - return err - } - - return nil -} - -func isWellKnownValue(fd *desc.FieldDescriptor) bool { - return !fd.IsRepeated() && fd.GetType() == descriptorpb.FieldDescriptorProto_TYPE_MESSAGE && - fd.GetMessageType().GetFullyQualifiedName() == "google.protobuf.Value" -} - -func isWellKnownListValue(fd *desc.FieldDescriptor) bool { - // we look for ListValue; but we also look for Value, which can be assigned a ListValue - return !fd.IsRepeated() && fd.GetType() == descriptorpb.FieldDescriptorProto_TYPE_MESSAGE && - (fd.GetMessageType().GetFullyQualifiedName() == "google.protobuf.ListValue" || - fd.GetMessageType().GetFullyQualifiedName() == "google.protobuf.Value") -} - -func unmarshalJsField(fd *desc.FieldDescriptor, r *jsReader, mf *MessageFactory, opts *jsonpb.Unmarshaler) (interface{}, error) { - t, err := r.peek() - if err != nil { - return nil, err - } - if t == nil && !isWellKnownValue(fd) { - // if value is null, just return nil - // (unless field is google.protobuf.Value, in which case - // we fall through to parse it as an instance where its - // underlying value is set to a NullValue) - r.poll() - return nil, nil - } - - if t == json.Delim('{') && fd.IsMap() { - entryType := fd.GetMessageType() - keyType := entryType.FindFieldByNumber(1) - valueType := entryType.FindFieldByNumber(2) - mp := map[interface{}]interface{}{} - - // TODO: if there are just two map keys "key" and "value" and they have the right type of values, - // treat this JSON object as a single map entry message. (In keeping with support of map fields as - // if they were normal repeated field of entry messages as well as supporting a transition from - // optional to repeated...) - - if err := r.beginObject(); err != nil { - return nil, err - } - for r.hasNext() { - kk, err := unmarshalJsFieldElement(keyType, r, mf, opts, false) - if err != nil { - return nil, err - } - vv, err := unmarshalJsFieldElement(valueType, r, mf, opts, true) - if err != nil { - return nil, err - } - mp[kk] = vv - } - if err := r.endObject(); err != nil { - return nil, err - } - - return mp, nil - } else if t == json.Delim('[') && !isWellKnownListValue(fd) { - // We support parsing an array, even if field is not repeated, to mimic support in proto - // binary wire format that supports changing an optional field to repeated and vice versa. - // If the field is not repeated, we only keep the last value in the array. - - if err := r.beginArray(); err != nil { - return nil, err - } - var sl []interface{} - var v interface{} - for r.hasNext() { - var err error - v, err = unmarshalJsFieldElement(fd, r, mf, opts, false) - if err != nil { - return nil, err - } - if fd.IsRepeated() && v != nil { - sl = append(sl, v) - } - } - if err := r.endArray(); err != nil { - return nil, err - } - if fd.IsMap() { - mp := map[interface{}]interface{}{} - for _, m := range sl { - msg := m.(*Message) - kk, err := msg.TryGetFieldByNumber(1) - if err != nil { - return nil, err - } - vv, err := msg.TryGetFieldByNumber(2) - if err != nil { - return nil, err - } - mp[kk] = vv - } - return mp, nil - } else if fd.IsRepeated() { - return sl, nil - } else { - return v, nil - } - } else { - // We support parsing a singular value, even if field is repeated, to mimic support in proto - // binary wire format that supports changing an optional field to repeated and vice versa. - // If the field is repeated, we store value as singleton slice of that one value. - - v, err := unmarshalJsFieldElement(fd, r, mf, opts, false) - if err != nil { - return nil, err - } - if v == nil { - return nil, nil - } - if fd.IsRepeated() { - return []interface{}{v}, nil - } else { - return v, nil - } - } -} - -func unmarshalJsFieldElement(fd *desc.FieldDescriptor, r *jsReader, mf *MessageFactory, opts *jsonpb.Unmarshaler, allowNilMessage bool) (interface{}, error) { - t, err := r.peek() - if err != nil { - return nil, err - } - - switch fd.GetType() { - case descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, - descriptorpb.FieldDescriptorProto_TYPE_GROUP: - - if t == nil && allowNilMessage { - // if json is simply "null" return a nil pointer - r.poll() - return nilMessage(fd.GetMessageType()), nil - } - - m := mf.NewMessage(fd.GetMessageType()) - if dm, ok := m.(*Message); ok { - if err := dm.unmarshalJson(r, opts); err != nil { - return nil, err - } - } else { - var msg json.RawMessage - if err := json.NewDecoder(r.unread()).Decode(&msg); err != nil { - return nil, err - } - if err := r.skip(); err != nil { - return nil, err - } - if err := opts.Unmarshal(bytes.NewReader([]byte(msg)), m); err != nil { - return nil, err - } - } - return m, nil - - case descriptorpb.FieldDescriptorProto_TYPE_ENUM: - if e, err := r.nextNumber(); err != nil { - return nil, err - } else { - // value could be string or number - if i, err := e.Int64(); err != nil { - // number cannot be parsed, so see if it's an enum value name - vd := fd.GetEnumType().FindValueByName(string(e)) - if vd != nil { - return vd.GetNumber(), nil - } else { - return nil, fmt.Errorf("enum %q does not have value named %q", fd.GetEnumType().GetFullyQualifiedName(), e) - } - } else if i > math.MaxInt32 || i < math.MinInt32 { - return nil, NumericOverflowError - } else { - return int32(i), err - } - } - - case descriptorpb.FieldDescriptorProto_TYPE_INT32, - descriptorpb.FieldDescriptorProto_TYPE_SINT32, - descriptorpb.FieldDescriptorProto_TYPE_SFIXED32: - if i, err := r.nextInt(); err != nil { - return nil, err - } else if i > math.MaxInt32 || i < math.MinInt32 { - return nil, NumericOverflowError - } else { - return int32(i), err - } - - case descriptorpb.FieldDescriptorProto_TYPE_INT64, - descriptorpb.FieldDescriptorProto_TYPE_SINT64, - descriptorpb.FieldDescriptorProto_TYPE_SFIXED64: - return r.nextInt() - - case descriptorpb.FieldDescriptorProto_TYPE_UINT32, - descriptorpb.FieldDescriptorProto_TYPE_FIXED32: - if i, err := r.nextUint(); err != nil { - return nil, err - } else if i > math.MaxUint32 { - return nil, NumericOverflowError - } else { - return uint32(i), err - } - - case descriptorpb.FieldDescriptorProto_TYPE_UINT64, - descriptorpb.FieldDescriptorProto_TYPE_FIXED64: - return r.nextUint() - - case descriptorpb.FieldDescriptorProto_TYPE_BOOL: - if str, ok := t.(string); ok { - if str == "true" { - r.poll() // consume token - return true, err - } else if str == "false" { - r.poll() // consume token - return false, err - } - } - return r.nextBool() - - case descriptorpb.FieldDescriptorProto_TYPE_FLOAT: - if f, err := r.nextFloat(); err != nil { - return nil, err - } else { - return float32(f), nil - } - - case descriptorpb.FieldDescriptorProto_TYPE_DOUBLE: - return r.nextFloat() - - case descriptorpb.FieldDescriptorProto_TYPE_BYTES: - return r.nextBytes() - - case descriptorpb.FieldDescriptorProto_TYPE_STRING: - return r.nextString() - - default: - return nil, fmt.Errorf("unknown field type: %v", fd.GetType()) - } -} - -type jsReader struct { - reader *bytes.Reader - dec *json.Decoder - current json.Token - peeked bool -} - -func newJsReader(b []byte) *jsReader { - reader := bytes.NewReader(b) - dec := json.NewDecoder(reader) - dec.UseNumber() - return &jsReader{reader: reader, dec: dec} -} - -func (r *jsReader) unread() io.Reader { - bufs := make([]io.Reader, 3) - var peeked []byte - if r.peeked { - if _, ok := r.current.(json.Delim); ok { - peeked = []byte(fmt.Sprintf("%v", r.current)) - } else { - peeked, _ = json.Marshal(r.current) - } - } - readerCopy := *r.reader - decCopy := *r.dec - - bufs[0] = bytes.NewReader(peeked) - bufs[1] = decCopy.Buffered() - bufs[2] = &readerCopy - return &concatReader{bufs: bufs} -} - -func (r *jsReader) hasNext() bool { - return r.dec.More() -} - -func (r *jsReader) peek() (json.Token, error) { - if r.peeked { - return r.current, nil - } - t, err := r.dec.Token() - if err != nil { - return nil, err - } - r.peeked = true - r.current = t - return t, nil -} - -func (r *jsReader) poll() (json.Token, error) { - if r.peeked { - ret := r.current - r.current = nil - r.peeked = false - return ret, nil - } - return r.dec.Token() -} - -func (r *jsReader) beginObject() error { - _, err := r.expect(func(t json.Token) bool { return t == json.Delim('{') }, nil, "start of JSON object: '{'") - return err -} - -func (r *jsReader) endObject() error { - _, err := r.expect(func(t json.Token) bool { return t == json.Delim('}') }, nil, "end of JSON object: '}'") - return err -} - -func (r *jsReader) beginArray() error { - _, err := r.expect(func(t json.Token) bool { return t == json.Delim('[') }, nil, "start of array: '['") - return err -} - -func (r *jsReader) endArray() error { - _, err := r.expect(func(t json.Token) bool { return t == json.Delim(']') }, nil, "end of array: ']'") - return err -} - -func (r *jsReader) nextObjectKey() (string, error) { - return r.nextString() -} - -func (r *jsReader) nextString() (string, error) { - t, err := r.expect(func(t json.Token) bool { _, ok := t.(string); return ok }, "", "string") - if err != nil { - return "", err - } - return t.(string), nil -} - -func (r *jsReader) nextBytes() ([]byte, error) { - str, err := r.nextString() - if err != nil { - return nil, err - } - return base64.StdEncoding.DecodeString(str) -} - -func (r *jsReader) nextBool() (bool, error) { - t, err := r.expect(func(t json.Token) bool { _, ok := t.(bool); return ok }, false, "boolean") - if err != nil { - return false, err - } - return t.(bool), nil -} - -func (r *jsReader) nextInt() (int64, error) { - n, err := r.nextNumber() - if err != nil { - return 0, err - } - return n.Int64() -} - -func (r *jsReader) nextUint() (uint64, error) { - n, err := r.nextNumber() - if err != nil { - return 0, err - } - return strconv.ParseUint(string(n), 10, 64) -} - -func (r *jsReader) nextFloat() (float64, error) { - n, err := r.nextNumber() - if err != nil { - return 0, err - } - return n.Float64() -} - -func (r *jsReader) nextNumber() (json.Number, error) { - t, err := r.expect(func(t json.Token) bool { return reflect.TypeOf(t).Kind() == reflect.String }, "0", "number") - if err != nil { - return "", err - } - switch t := t.(type) { - case json.Number: - return t, nil - case string: - return json.Number(t), nil - } - return "", fmt.Errorf("expecting a number but got %v", t) -} - -func (r *jsReader) skip() error { - t, err := r.poll() - if err != nil { - return err - } - if t == json.Delim('[') { - if err := r.skipArray(); err != nil { - return err - } - } else if t == json.Delim('{') { - if err := r.skipObject(); err != nil { - return err - } - } - return nil -} - -func (r *jsReader) skipArray() error { - for r.hasNext() { - if err := r.skip(); err != nil { - return err - } - } - if err := r.endArray(); err != nil { - return err - } - return nil -} - -func (r *jsReader) skipObject() error { - for r.hasNext() { - // skip object key - if err := r.skip(); err != nil { - return err - } - // and value - if err := r.skip(); err != nil { - return err - } - } - if err := r.endObject(); err != nil { - return err - } - return nil -} - -func (r *jsReader) expect(predicate func(json.Token) bool, ifNil interface{}, expected string) (interface{}, error) { - t, err := r.poll() - if err != nil { - return nil, err - } - if t == nil && ifNil != nil { - return ifNil, nil - } - if !predicate(t) { - return t, fmt.Errorf("bad input: expecting %s ; instead got %v", expected, t) - } - return t, nil -} - -type concatReader struct { - bufs []io.Reader - curr int -} - -func (r *concatReader) Read(p []byte) (n int, err error) { - for { - if r.curr >= len(r.bufs) { - err = io.EOF - return - } - var c int - c, err = r.bufs[r.curr].Read(p) - n += c - if err != io.EOF { - return - } - r.curr++ - p = p[c:] - } -} - -// AnyResolver returns a jsonpb.AnyResolver that uses the given file descriptors -// to resolve message names. It uses the given factory, which may be nil, to -// instantiate messages. The messages that it returns when resolving a type name -// may often be dynamic messages. -func AnyResolver(mf *MessageFactory, files ...*desc.FileDescriptor) jsonpb.AnyResolver { - return &anyResolver{mf: mf, files: files} -} - -type anyResolver struct { - mf *MessageFactory - files []*desc.FileDescriptor - ignored map[*desc.FileDescriptor]struct{} - other jsonpb.AnyResolver -} - -func wrapResolver(r jsonpb.AnyResolver, mf *MessageFactory, f *desc.FileDescriptor) (jsonpb.AnyResolver, bool) { - if r, ok := r.(*anyResolver); ok { - if _, ok := r.ignored[f]; ok { - // if the current resolver is ignoring this file, it's because another - // (upstream) resolver is already handling it, so nothing to do - return r, false - } - for _, file := range r.files { - if file == f { - // no need to wrap! - return r, false - } - } - // ignore files that will be checked by the resolver we're wrapping - // (we'll just delegate and let it search those files) - ignored := map[*desc.FileDescriptor]struct{}{} - for i := range r.ignored { - ignored[i] = struct{}{} - } - ignore(r.files, ignored) - return &anyResolver{mf: mf, files: []*desc.FileDescriptor{f}, ignored: ignored, other: r}, true - } - return &anyResolver{mf: mf, files: []*desc.FileDescriptor{f}, other: r}, true -} - -func ignore(files []*desc.FileDescriptor, ignored map[*desc.FileDescriptor]struct{}) { - for _, f := range files { - if _, ok := ignored[f]; ok { - continue - } - ignored[f] = struct{}{} - ignore(f.GetDependencies(), ignored) - } -} - -func (r *anyResolver) Resolve(typeUrl string) (proto.Message, error) { - mname := typeUrl - if slash := strings.LastIndex(mname, "/"); slash >= 0 { - mname = mname[slash+1:] - } - - // see if the user-specified resolver is able to do the job - if r.other != nil { - msg, err := r.other.Resolve(typeUrl) - if err == nil { - return msg, nil - } - } - - // try to find the message in our known set of files - checked := map[*desc.FileDescriptor]struct{}{} - for _, f := range r.files { - md := r.findMessage(f, mname, checked) - if md != nil { - return r.mf.NewMessage(md), nil - } - } - // failing that, see if the message factory knows about this type - var ktr *KnownTypeRegistry - if r.mf != nil { - ktr = r.mf.ktr - } else { - ktr = (*KnownTypeRegistry)(nil) - } - m := ktr.CreateIfKnown(mname) - if m != nil { - return m, nil - } - - // no other resolver to fallback to? mimic default behavior - 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 -} - -func (r *anyResolver) findMessage(fd *desc.FileDescriptor, msgName string, checked map[*desc.FileDescriptor]struct{}) *desc.MessageDescriptor { - // if this is an ignored descriptor, skip - if _, ok := r.ignored[fd]; ok { - return nil - } - - // bail if we've already checked this file - if _, ok := checked[fd]; ok { - return nil - } - checked[fd] = struct{}{} - - // see if this file has the message - md := fd.FindMessage(msgName) - if md != nil { - return md - } - - // if not, recursively search the file's imports - for _, dep := range fd.GetDependencies() { - md = r.findMessage(dep, msgName, checked) - if md != nil { - return md - } - } - return nil -} - -var _ jsonpb.AnyResolver = (*anyResolver)(nil) diff --git a/vendor/github.com/jhump/protoreflect/dynamic/maps_1.11.go b/vendor/github.com/jhump/protoreflect/dynamic/maps_1.11.go deleted file mode 100644 index 69969fc5..00000000 --- a/vendor/github.com/jhump/protoreflect/dynamic/maps_1.11.go +++ /dev/null @@ -1,131 +0,0 @@ -//go:build !go1.12 -// +build !go1.12 - -package dynamic - -import ( - "reflect" - - "github.com/jhump/protoreflect/desc" -) - -// Pre-Go-1.12, we must use reflect.Value.MapKeys to reflectively -// iterate a map. (We can be more efficient in Go 1.12 and up...) - -func mapsEqual(a, b reflect.Value) bool { - if a.Len() != b.Len() { - return false - } - if a.Len() == 0 && b.Len() == 0 { - // Optimize the case where maps are frequently empty because MapKeys() - // function allocates heavily. - return true - } - - for _, k := range a.MapKeys() { - av := a.MapIndex(k) - bv := b.MapIndex(k) - if !bv.IsValid() { - return false - } - if !fieldsEqual(av.Interface(), bv.Interface()) { - return false - } - } - return true -} - -func validFieldValueForMapField(fd *desc.FieldDescriptor, val reflect.Value) (interface{}, error) { - // make a defensive copy while we check the contents - // (also converts to map[interface{}]interface{} if it's some other type) - keyField := fd.GetMessageType().GetFields()[0] - valField := fd.GetMessageType().GetFields()[1] - m := map[interface{}]interface{}{} - for _, k := range val.MapKeys() { - if k.Kind() == reflect.Interface { - // unwrap it - k = reflect.ValueOf(k.Interface()) - } - kk, err := validElementFieldValueForRv(keyField, k, false) - if err != nil { - return nil, err - } - v := val.MapIndex(k) - if v.Kind() == reflect.Interface { - // unwrap it - v = reflect.ValueOf(v.Interface()) - } - vv, err := validElementFieldValueForRv(valField, v, true) - if err != nil { - return nil, err - } - m[kk] = vv - } - return m, nil -} - -func canConvertMap(src reflect.Value, target reflect.Type) bool { - kt := target.Key() - vt := target.Elem() - for _, k := range src.MapKeys() { - if !canConvert(k, kt) { - return false - } - if !canConvert(src.MapIndex(k), vt) { - return false - } - } - return true -} - -func mergeMapVal(src, target reflect.Value, targetType reflect.Type, deterministic bool) error { - tkt := targetType.Key() - tvt := targetType.Elem() - for _, k := range src.MapKeys() { - v := src.MapIndex(k) - skt := k.Type() - svt := v.Type() - var nk, nv reflect.Value - if tkt == skt { - nk = k - } else if tkt.Kind() == reflect.Ptr && tkt.Elem() == skt { - nk = k.Addr() - } else { - nk = reflect.New(tkt).Elem() - if err := mergeVal(k, nk, deterministic); err != nil { - return err - } - } - if tvt == svt { - nv = v - } else if tvt.Kind() == reflect.Ptr && tvt.Elem() == svt { - nv = v.Addr() - } else { - nv = reflect.New(tvt).Elem() - if err := mergeVal(v, nv, deterministic); err != nil { - return err - } - } - if target.IsNil() { - target.Set(reflect.MakeMap(targetType)) - } - target.SetMapIndex(nk, nv) - } - return nil -} - -func mergeMapField(m *Message, fd *desc.FieldDescriptor, rv reflect.Value) error { - for _, k := range rv.MapKeys() { - if k.Kind() == reflect.Interface && !k.IsNil() { - k = k.Elem() - } - v := rv.MapIndex(k) - if v.Kind() == reflect.Interface && !v.IsNil() { - v = v.Elem() - } - if err := m.putMapField(fd, k.Interface(), v.Interface()); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/jhump/protoreflect/dynamic/maps_1.12.go b/vendor/github.com/jhump/protoreflect/dynamic/maps_1.12.go deleted file mode 100644 index fb353cfc..00000000 --- a/vendor/github.com/jhump/protoreflect/dynamic/maps_1.12.go +++ /dev/null @@ -1,139 +0,0 @@ -//go:build go1.12 -// +build go1.12 - -package dynamic - -import ( - "reflect" - - "github.com/jhump/protoreflect/desc" -) - -// With Go 1.12 and above, we can use reflect.Value.MapRange to iterate -// over maps more efficiently than using reflect.Value.MapKeys. - -func mapsEqual(a, b reflect.Value) bool { - if a.Len() != b.Len() { - return false - } - if a.Len() == 0 && b.Len() == 0 { - // Optimize the case where maps are frequently empty - return true - } - - iter := a.MapRange() - for iter.Next() { - k := iter.Key() - av := iter.Value() - bv := b.MapIndex(k) - if !bv.IsValid() { - return false - } - if !fieldsEqual(av.Interface(), bv.Interface()) { - return false - } - } - return true -} - -func validFieldValueForMapField(fd *desc.FieldDescriptor, val reflect.Value) (interface{}, error) { - // make a defensive copy while we check the contents - // (also converts to map[interface{}]interface{} if it's some other type) - keyField := fd.GetMessageType().GetFields()[0] - valField := fd.GetMessageType().GetFields()[1] - m := map[interface{}]interface{}{} - iter := val.MapRange() - for iter.Next() { - k := iter.Key() - if k.Kind() == reflect.Interface { - // unwrap it - k = reflect.ValueOf(k.Interface()) - } - kk, err := validElementFieldValueForRv(keyField, k, false) - if err != nil { - return nil, err - } - v := iter.Value() - if v.Kind() == reflect.Interface { - // unwrap it - v = reflect.ValueOf(v.Interface()) - } - vv, err := validElementFieldValueForRv(valField, v, true) - if err != nil { - return nil, err - } - m[kk] = vv - } - return m, nil -} - -func canConvertMap(src reflect.Value, target reflect.Type) bool { - kt := target.Key() - vt := target.Elem() - iter := src.MapRange() - for iter.Next() { - if !canConvert(iter.Key(), kt) { - return false - } - if !canConvert(iter.Value(), vt) { - return false - } - } - return true -} - -func mergeMapVal(src, target reflect.Value, targetType reflect.Type, deterministic bool) error { - tkt := targetType.Key() - tvt := targetType.Elem() - iter := src.MapRange() - for iter.Next() { - k := iter.Key() - v := iter.Value() - skt := k.Type() - svt := v.Type() - var nk, nv reflect.Value - if tkt == skt { - nk = k - } else if tkt.Kind() == reflect.Ptr && tkt.Elem() == skt { - nk = k.Addr() - } else { - nk = reflect.New(tkt).Elem() - if err := mergeVal(k, nk, deterministic); err != nil { - return err - } - } - if tvt == svt { - nv = v - } else if tvt.Kind() == reflect.Ptr && tvt.Elem() == svt { - nv = v.Addr() - } else { - nv = reflect.New(tvt).Elem() - if err := mergeVal(v, nv, deterministic); err != nil { - return err - } - } - if target.IsNil() { - target.Set(reflect.MakeMap(targetType)) - } - target.SetMapIndex(nk, nv) - } - return nil -} - -func mergeMapField(m *Message, fd *desc.FieldDescriptor, rv reflect.Value) error { - iter := rv.MapRange() - for iter.Next() { - k := iter.Key() - v := iter.Value() - if k.Kind() == reflect.Interface && !k.IsNil() { - k = k.Elem() - } - if v.Kind() == reflect.Interface && !v.IsNil() { - v = v.Elem() - } - if err := m.putMapField(fd, k.Interface(), v.Interface()); err != nil { - return err - } - } - return nil -} diff --git a/vendor/github.com/jhump/protoreflect/dynamic/merge.go b/vendor/github.com/jhump/protoreflect/dynamic/merge.go deleted file mode 100644 index ce727fd5..00000000 --- a/vendor/github.com/jhump/protoreflect/dynamic/merge.go +++ /dev/null @@ -1,100 +0,0 @@ -package dynamic - -import ( - "errors" - "reflect" - - "github.com/golang/protobuf/proto" - - "github.com/jhump/protoreflect/desc" -) - -// Merge merges the given source message into the given destination message. Use -// use this instead of proto.Merge when one or both of the messages might be a -// a dynamic message. If there is a problem merging the messages, such as the -// two messages having different types, then this method will panic (just as -// proto.Merges does). -func Merge(dst, src proto.Message) { - if dm, ok := dst.(*Message); ok { - if err := dm.MergeFrom(src); err != nil { - panic(err.Error()) - } - } else if dm, ok := src.(*Message); ok { - if err := dm.MergeInto(dst); err != nil { - panic(err.Error()) - } - } else { - proto.Merge(dst, src) - } -} - -// TryMerge merges the given source message into the given destination message. -// You can use this instead of proto.Merge when one or both of the messages -// might be a dynamic message. Unlike proto.Merge, this method will return an -// error on failure instead of panic'ing. -func TryMerge(dst, src proto.Message) error { - if dm, ok := dst.(*Message); ok { - if err := dm.MergeFrom(src); err != nil { - return err - } - } else if dm, ok := src.(*Message); ok { - if err := dm.MergeInto(dst); err != nil { - return err - } - } else { - // proto.Merge panics on bad input, so we first verify - // inputs and return error instead of panic - out := reflect.ValueOf(dst) - if out.IsNil() { - return errors.New("proto: nil destination") - } - in := reflect.ValueOf(src) - if in.Type() != out.Type() { - return errors.New("proto: type mismatch") - } - proto.Merge(dst, src) - } - return nil -} - -func mergeField(m *Message, fd *desc.FieldDescriptor, val interface{}) error { - rv := reflect.ValueOf(val) - - if fd.IsMap() && rv.Kind() == reflect.Map { - return mergeMapField(m, fd, rv) - } - - if fd.IsRepeated() && rv.Kind() == reflect.Slice && rv.Type() != typeOfBytes { - for i := 0; i < rv.Len(); i++ { - e := rv.Index(i) - if e.Kind() == reflect.Interface && !e.IsNil() { - e = e.Elem() - } - if err := m.addRepeatedField(fd, e.Interface()); err != nil { - return err - } - } - return nil - } - - if fd.IsRepeated() { - return m.addRepeatedField(fd, val) - } else if fd.GetMessageType() == nil { - return m.setField(fd, val) - } - - // it's a message type, so we want to merge contents - var err error - if val, err = validFieldValue(fd, val); err != nil { - return err - } - - existing, _ := m.doGetField(fd, true) - if existing != nil && !reflect.ValueOf(existing).IsNil() { - return TryMerge(existing.(proto.Message), val.(proto.Message)) - } - - // no existing message, so just set field - m.internalSetField(fd, val) - return nil -} diff --git a/vendor/github.com/jhump/protoreflect/dynamic/message_factory.go b/vendor/github.com/jhump/protoreflect/dynamic/message_factory.go deleted file mode 100644 index 683e7b33..00000000 --- a/vendor/github.com/jhump/protoreflect/dynamic/message_factory.go +++ /dev/null @@ -1,207 +0,0 @@ -package dynamic - -import ( - "reflect" - "sync" - - "github.com/golang/protobuf/proto" - - "github.com/jhump/protoreflect/desc" -) - -// MessageFactory can be used to create new empty message objects. A default instance -// (without extension registry or known-type registry specified) will always return -// dynamic messages (e.g. type will be *dynamic.Message) except for "well-known" types. -// The well-known types include primitive wrapper types and a handful of other special -// types defined in standard protobuf definitions, like Any, Duration, and Timestamp. -type MessageFactory struct { - er *ExtensionRegistry - ktr *KnownTypeRegistry -} - -// NewMessageFactoryWithExtensionRegistry creates a new message factory where any -// dynamic messages produced will use the given extension registry to recognize and -// parse extension fields. -func NewMessageFactoryWithExtensionRegistry(er *ExtensionRegistry) *MessageFactory { - return NewMessageFactoryWithRegistries(er, nil) -} - -// NewMessageFactoryWithKnownTypeRegistry creates a new message factory where the -// known types, per the given registry, will be returned as normal protobuf messages -// (e.g. generated structs, instead of dynamic messages). -func NewMessageFactoryWithKnownTypeRegistry(ktr *KnownTypeRegistry) *MessageFactory { - return NewMessageFactoryWithRegistries(nil, ktr) -} - -// NewMessageFactoryWithDefaults creates a new message factory where all "default" types -// (those for which protoc-generated code is statically linked into the Go program) are -// known types. If any dynamic messages are produced, they will recognize and parse all -// "default" extension fields. This is the equivalent of: -// -// NewMessageFactoryWithRegistries( -// NewExtensionRegistryWithDefaults(), -// NewKnownTypeRegistryWithDefaults()) -func NewMessageFactoryWithDefaults() *MessageFactory { - return NewMessageFactoryWithRegistries(NewExtensionRegistryWithDefaults(), NewKnownTypeRegistryWithDefaults()) -} - -// NewMessageFactoryWithRegistries creates a new message factory with the given extension -// and known type registries. -func NewMessageFactoryWithRegistries(er *ExtensionRegistry, ktr *KnownTypeRegistry) *MessageFactory { - return &MessageFactory{ - er: er, - ktr: ktr, - } -} - -// NewMessage creates a new empty message that corresponds to the given descriptor. -// If the given descriptor describes a "known type" then that type is instantiated. -// Otherwise, an empty dynamic message is returned. -func (f *MessageFactory) NewMessage(md *desc.MessageDescriptor) proto.Message { - var ktr *KnownTypeRegistry - if f != nil { - ktr = f.ktr - } - if m := ktr.CreateIfKnown(md.GetFullyQualifiedName()); m != nil { - return m - } - return NewMessageWithMessageFactory(md, f) -} - -// NewDynamicMessage creates a new empty dynamic message that corresponds to the given -// descriptor. This is like f.NewMessage(md) except the known type registry is not -// consulted so the return value is always a dynamic message. -// -// This is also like dynamic.NewMessage(md) except that the returned message will use -// this factory when creating other messages, like during de-serialization of fields -// that are themselves message types. -func (f *MessageFactory) NewDynamicMessage(md *desc.MessageDescriptor) *Message { - return NewMessageWithMessageFactory(md, f) -} - -// GetKnownTypeRegistry returns the known type registry that this factory uses to -// instantiate known (e.g. generated) message types. -func (f *MessageFactory) GetKnownTypeRegistry() *KnownTypeRegistry { - if f == nil { - return nil - } - return f.ktr -} - -// GetExtensionRegistry returns the extension registry that this factory uses to -// create dynamic messages. The registry is used by dynamic messages to recognize -// and parse extension fields during de-serialization. -func (f *MessageFactory) GetExtensionRegistry() *ExtensionRegistry { - if f == nil { - return nil - } - return f.er -} - -type wkt interface { - XXX_WellKnownType() string -} - -var typeOfWkt = reflect.TypeOf((*wkt)(nil)).Elem() - -// KnownTypeRegistry is a registry of known message types, as identified by their -// fully-qualified name. A known message type is one for which a protoc-generated -// struct exists, so a dynamic message is not necessary to represent it. A -// MessageFactory uses a KnownTypeRegistry to decide whether to create a generated -// struct or a dynamic message. The zero-value registry (including the behavior of -// a nil pointer) only knows about the "well-known types" in protobuf. These -// include only the wrapper types and a handful of other special types like Any, -// Duration, and Timestamp. -type KnownTypeRegistry struct { - excludeWkt bool - includeDefault bool - mu sync.RWMutex - types map[string]reflect.Type -} - -// NewKnownTypeRegistryWithDefaults creates a new registry that knows about all -// "default" types (those for which protoc-generated code is statically linked -// into the Go program). -func NewKnownTypeRegistryWithDefaults() *KnownTypeRegistry { - return &KnownTypeRegistry{includeDefault: true} -} - -// NewKnownTypeRegistryWithoutWellKnownTypes creates a new registry that does *not* -// include the "well-known types" in protobuf. So even well-known types would be -// represented by a dynamic message. -func NewKnownTypeRegistryWithoutWellKnownTypes() *KnownTypeRegistry { - return &KnownTypeRegistry{excludeWkt: true} -} - -// AddKnownType adds the types of the given messages as known types. -func (r *KnownTypeRegistry) AddKnownType(kts ...proto.Message) { - r.mu.Lock() - defer r.mu.Unlock() - if r.types == nil { - r.types = map[string]reflect.Type{} - } - for _, kt := range kts { - r.types[proto.MessageName(kt)] = reflect.TypeOf(kt) - } -} - -// CreateIfKnown will construct an instance of the given message if it is a known type. -// If the given name is unknown, nil is returned. -func (r *KnownTypeRegistry) CreateIfKnown(messageName string) proto.Message { - msgType := r.GetKnownType(messageName) - if msgType == nil { - return nil - } - - if msgType.Kind() == reflect.Ptr { - return reflect.New(msgType.Elem()).Interface().(proto.Message) - } else { - return reflect.New(msgType).Elem().Interface().(proto.Message) - } -} - -func isWellKnownType(t reflect.Type) bool { - if t.Implements(typeOfWkt) { - return true - } - if msg, ok := reflect.Zero(t).Interface().(proto.Message); ok { - name := proto.MessageName(msg) - _, ok := wellKnownTypeNames[name] - return ok - } - return false -} - -// GetKnownType will return the reflect.Type for the given message name if it is -// known. If it is not known, nil is returned. -func (r *KnownTypeRegistry) GetKnownType(messageName string) reflect.Type { - if r == nil { - // a nil registry behaves the same as zero value instance: only know of well-known types - t := proto.MessageType(messageName) - if t != nil && isWellKnownType(t) { - return t - } - return nil - } - - if r.includeDefault { - t := proto.MessageType(messageName) - if t != nil && isMessage(t) { - return t - } - } else if !r.excludeWkt { - t := proto.MessageType(messageName) - if t != nil && isWellKnownType(t) { - return t - } - } - - r.mu.RLock() - defer r.mu.RUnlock() - return r.types[messageName] -} - -func isMessage(t reflect.Type) bool { - _, ok := reflect.Zero(t).Interface().(proto.Message) - return ok -} diff --git a/vendor/github.com/jhump/protoreflect/dynamic/text.go b/vendor/github.com/jhump/protoreflect/dynamic/text.go deleted file mode 100644 index 5680dc2d..00000000 --- a/vendor/github.com/jhump/protoreflect/dynamic/text.go +++ /dev/null @@ -1,1177 +0,0 @@ -package dynamic - -// Marshalling and unmarshalling of dynamic messages to/from proto's standard text format - -import ( - "bytes" - "fmt" - "io" - "math" - "reflect" - "sort" - "strconv" - "strings" - "text/scanner" - "unicode" - - "github.com/golang/protobuf/proto" - "google.golang.org/protobuf/types/descriptorpb" - - "github.com/jhump/protoreflect/codec" - "github.com/jhump/protoreflect/desc" -) - -// MarshalText serializes this message to bytes in the standard text format, -// returning an error if the operation fails. The resulting bytes will be a -// valid UTF8 string. -// -// This method uses a compact form: no newlines, and spaces between field -// identifiers and values are elided. -func (m *Message) MarshalText() ([]byte, error) { - var b indentBuffer - b.indentCount = -1 // no indentation - if err := m.marshalText(&b); err != nil { - return nil, err - } - return b.Bytes(), nil -} - -// MarshalTextIndent serializes this message to bytes in the standard text -// format, returning an error if the operation fails. The resulting bytes will -// be a valid UTF8 string. -// -// This method uses a "pretty-printed" form, with each field on its own line and -// spaces between field identifiers and values. -func (m *Message) MarshalTextIndent() ([]byte, error) { - var b indentBuffer - b.indent = " " // TODO: option for indent? - if err := m.marshalText(&b); err != nil { - return nil, err - } - return b.Bytes(), nil -} - -func (m *Message) marshalText(b *indentBuffer) error { - // TODO: option for emitting extended Any format? - first := true - // first the known fields - for _, tag := range m.knownFieldTags() { - itag := int32(tag) - v := m.values[itag] - fd := m.FindFieldDescriptor(itag) - if fd.IsMap() { - md := fd.GetMessageType() - kfd := md.FindFieldByNumber(1) - vfd := md.FindFieldByNumber(2) - mp := v.(map[interface{}]interface{}) - keys := make([]interface{}, 0, len(mp)) - for k := range mp { - keys = append(keys, k) - } - sort.Sort(sortable(keys)) - for _, mk := range keys { - mv := mp[mk] - err := b.maybeNext(&first) - if err != nil { - return err - } - err = marshalKnownFieldMapEntryText(b, fd, kfd, mk, vfd, mv) - if err != nil { - return err - } - } - } else if fd.IsRepeated() { - sl := v.([]interface{}) - for _, slv := range sl { - err := b.maybeNext(&first) - if err != nil { - return err - } - err = marshalKnownFieldText(b, fd, slv) - if err != nil { - return err - } - } - } else { - err := b.maybeNext(&first) - if err != nil { - return err - } - err = marshalKnownFieldText(b, fd, v) - if err != nil { - return err - } - } - } - // then the unknown fields - for _, tag := range m.unknownFieldTags() { - itag := int32(tag) - ufs := m.unknownFields[itag] - for _, uf := range ufs { - err := b.maybeNext(&first) - if err != nil { - return err - } - _, err = fmt.Fprintf(b, "%d", tag) - if err != nil { - return err - } - if uf.Encoding == proto.WireStartGroup { - err = b.WriteByte('{') - if err != nil { - return err - } - err = b.start() - if err != nil { - return err - } - in := codec.NewBuffer(uf.Contents) - err = marshalUnknownGroupText(b, in, true) - if err != nil { - return err - } - err = b.end() - if err != nil { - return err - } - err = b.WriteByte('}') - if err != nil { - return err - } - } else { - err = b.sep() - if err != nil { - return err - } - if uf.Encoding == proto.WireBytes { - err = writeString(b, string(uf.Contents)) - if err != nil { - return err - } - } else { - _, err = b.WriteString(strconv.FormatUint(uf.Value, 10)) - if err != nil { - return err - } - } - } - } - } - return nil -} - -func marshalKnownFieldMapEntryText(b *indentBuffer, fd *desc.FieldDescriptor, kfd *desc.FieldDescriptor, mk interface{}, vfd *desc.FieldDescriptor, mv interface{}) error { - var name string - if fd.IsExtension() { - name = fmt.Sprintf("[%s]", fd.GetFullyQualifiedName()) - } else { - name = fd.GetName() - } - _, err := b.WriteString(name) - if err != nil { - return err - } - err = b.sep() - if err != nil { - return err - } - - err = b.WriteByte('<') - if err != nil { - return err - } - err = b.start() - if err != nil { - return err - } - - err = marshalKnownFieldText(b, kfd, mk) - if err != nil { - return err - } - err = b.next() - if err != nil { - return err - } - if !isNil(mv) { - err = marshalKnownFieldText(b, vfd, mv) - if err != nil { - return err - } - } - - err = b.end() - if err != nil { - return err - } - return b.WriteByte('>') -} - -func marshalKnownFieldText(b *indentBuffer, fd *desc.FieldDescriptor, v interface{}) error { - group := fd.GetType() == descriptorpb.FieldDescriptorProto_TYPE_GROUP - if group { - var name string - if fd.IsExtension() { - name = fmt.Sprintf("[%s]", fd.GetMessageType().GetFullyQualifiedName()) - } else { - name = fd.GetMessageType().GetName() - } - _, err := b.WriteString(name) - if err != nil { - return err - } - } else { - var name string - if fd.IsExtension() { - name = fmt.Sprintf("[%s]", fd.GetFullyQualifiedName()) - } else { - name = fd.GetName() - } - _, err := b.WriteString(name) - if err != nil { - return err - } - err = b.sep() - if err != nil { - return err - } - } - rv := reflect.ValueOf(v) - switch rv.Kind() { - case reflect.Int32, reflect.Int64: - ed := fd.GetEnumType() - if ed != nil { - n := int32(rv.Int()) - vd := ed.FindValueByNumber(n) - if vd == nil { - _, err := b.WriteString(strconv.FormatInt(rv.Int(), 10)) - return err - } else { - _, err := b.WriteString(vd.GetName()) - return err - } - } else { - _, err := b.WriteString(strconv.FormatInt(rv.Int(), 10)) - return err - } - case reflect.Uint32, reflect.Uint64: - _, err := b.WriteString(strconv.FormatUint(rv.Uint(), 10)) - return err - case reflect.Float32, reflect.Float64: - f := rv.Float() - var str string - if math.IsNaN(f) { - str = "nan" - } else if math.IsInf(f, 1) { - str = "inf" - } else if math.IsInf(f, -1) { - str = "-inf" - } else { - var bits int - if rv.Kind() == reflect.Float32 { - bits = 32 - } else { - bits = 64 - } - str = strconv.FormatFloat(rv.Float(), 'g', -1, bits) - } - _, err := b.WriteString(str) - return err - case reflect.Bool: - _, err := b.WriteString(strconv.FormatBool(rv.Bool())) - return err - case reflect.Slice: - return writeString(b, string(rv.Bytes())) - case reflect.String: - return writeString(b, rv.String()) - default: - var err error - if group { - err = b.WriteByte('{') - } else { - err = b.WriteByte('<') - } - if err != nil { - return err - } - err = b.start() - if err != nil { - return err - } - // must be a message - if dm, ok := v.(*Message); ok { - err = dm.marshalText(b) - if err != nil { - return err - } - } else { - err = proto.CompactText(b, v.(proto.Message)) - if err != nil { - return err - } - } - err = b.end() - if err != nil { - return err - } - if group { - return b.WriteByte('}') - } else { - return b.WriteByte('>') - } - } -} - -// writeString writes a string in the protocol buffer text format. -// It is similar to strconv.Quote except we don't use Go escape sequences, -// we treat the string as a byte sequence, and we use octal escapes. -// These differences are to maintain interoperability with the other -// languages' implementations of the text format. -func writeString(b *indentBuffer, s string) error { - // use WriteByte here to get any needed indent - if err := b.WriteByte('"'); err != nil { - return err - } - // Loop over the bytes, not the runes. - for i := 0; i < len(s); i++ { - var err error - // Divergence from C++: we don't escape apostrophes. - // There's no need to escape them, and the C++ parser - // copes with a naked apostrophe. - switch c := s[i]; c { - case '\n': - _, err = b.WriteString("\\n") - case '\r': - _, err = b.WriteString("\\r") - case '\t': - _, err = b.WriteString("\\t") - case '"': - _, err = b.WriteString("\\\"") - case '\\': - _, err = b.WriteString("\\\\") - default: - if c >= 0x20 && c < 0x7f { - err = b.WriteByte(c) - } else { - _, err = fmt.Fprintf(b, "\\%03o", c) - } - } - if err != nil { - return err - } - } - return b.WriteByte('"') -} - -func marshalUnknownGroupText(b *indentBuffer, in *codec.Buffer, topLevel bool) error { - first := true - for { - if in.EOF() { - if topLevel { - return nil - } - // this is a nested message: we are expecting an end-group tag, not EOF! - return io.ErrUnexpectedEOF - } - tag, wireType, err := in.DecodeTagAndWireType() - if err != nil { - return err - } - if wireType == proto.WireEndGroup { - return nil - } - err = b.maybeNext(&first) - if err != nil { - return err - } - _, err = fmt.Fprintf(b, "%d", tag) - if err != nil { - return err - } - if wireType == proto.WireStartGroup { - err = b.WriteByte('{') - if err != nil { - return err - } - err = b.start() - if err != nil { - return err - } - err = marshalUnknownGroupText(b, in, false) - if err != nil { - return err - } - err = b.end() - if err != nil { - return err - } - err = b.WriteByte('}') - if err != nil { - return err - } - continue - } else { - err = b.sep() - if err != nil { - return err - } - if wireType == proto.WireBytes { - contents, err := in.DecodeRawBytes(false) - if err != nil { - return err - } - err = writeString(b, string(contents)) - if err != nil { - return err - } - } else { - var v uint64 - switch wireType { - case proto.WireVarint: - v, err = in.DecodeVarint() - case proto.WireFixed32: - v, err = in.DecodeFixed32() - case proto.WireFixed64: - v, err = in.DecodeFixed64() - default: - return proto.ErrInternalBadWireType - } - if err != nil { - return err - } - _, err = b.WriteString(strconv.FormatUint(v, 10)) - if err != nil { - return err - } - } - } - } -} - -// UnmarshalText de-serializes the message that is present, in text format, in -// the given bytes into this message. It first resets the current message. It -// returns an error if the given bytes do not contain a valid encoding of this -// message type in the standard text format -func (m *Message) UnmarshalText(text []byte) error { - m.Reset() - if err := m.UnmarshalMergeText(text); err != nil { - return err - } - return m.Validate() -} - -// UnmarshalMergeText de-serializes the message that is present, in text format, -// in the given bytes into this message. Unlike UnmarshalText, it does not first -// reset the message, instead merging the data in the given bytes into the -// existing data in this message. -func (m *Message) UnmarshalMergeText(text []byte) error { - return m.unmarshalText(newReader(text), tokenEOF) -} - -func (m *Message) unmarshalText(tr *txtReader, end tokenType) error { - for { - tok := tr.next() - if tok.tokTyp == end { - return nil - } - if tok.tokTyp == tokenEOF { - return io.ErrUnexpectedEOF - } - var fd *desc.FieldDescriptor - var extendedAnyType *desc.MessageDescriptor - if tok.tokTyp == tokenInt { - // tag number (indicates unknown field) - tag, err := strconv.ParseInt(tok.val.(string), 10, 32) - if err != nil { - return err - } - itag := int32(tag) - fd = m.FindFieldDescriptor(itag) - if fd == nil { - // can't parse the value w/out field descriptor, so skip it - tok = tr.next() - if tok.tokTyp == tokenEOF { - return io.ErrUnexpectedEOF - } else if tok.tokTyp == tokenOpenBrace { - if err := skipMessageText(tr, true); err != nil { - return err - } - } else if tok.tokTyp == tokenColon { - if err := skipFieldValueText(tr); err != nil { - return err - } - } else { - return textError(tok, "Expecting a colon ':' or brace '{'; instead got %q", tok.txt) - } - tok = tr.peek() - if tok.tokTyp.IsSep() { - tr.next() // consume separator - } - continue - } - } else { - fieldName, err := unmarshalFieldNameText(tr, tok) - if err != nil { - return err - } - fd = m.FindFieldDescriptorByName(fieldName) - if fd == nil { - // See if it's a group name - for _, field := range m.md.GetFields() { - if field.GetType() == descriptorpb.FieldDescriptorProto_TYPE_GROUP && field.GetMessageType().GetName() == fieldName { - fd = field - break - } - } - if fd == nil { - // maybe this is an extended Any - if m.md.GetFullyQualifiedName() == "google.protobuf.Any" && fieldName[0] == '[' && strings.Contains(fieldName, "/") { - // strip surrounding "[" and "]" and extract type name from URL - typeUrl := fieldName[1 : len(fieldName)-1] - mname := typeUrl - if slash := strings.LastIndex(mname, "/"); slash >= 0 { - mname = mname[slash+1:] - } - // TODO: add a way to weave an AnyResolver to this point - extendedAnyType = findMessageDescriptor(mname, m.md.GetFile()) - if extendedAnyType == nil { - return textError(tok, "could not parse Any with unknown type URL %q", fieldName) - } - // field 1 is "type_url" - typeUrlField := m.md.FindFieldByNumber(1) - if err := m.TrySetField(typeUrlField, typeUrl); err != nil { - return err - } - } else { - // TODO: add a flag to just ignore unrecognized field names - return textError(tok, "%q is not a recognized field name of %q", fieldName, m.md.GetFullyQualifiedName()) - } - } - } - } - tok = tr.next() - if tok.tokTyp == tokenEOF { - return io.ErrUnexpectedEOF - } - if extendedAnyType != nil { - // consume optional colon; make sure this is a "start message" token - if tok.tokTyp == tokenColon { - tok = tr.next() - if tok.tokTyp == tokenEOF { - return io.ErrUnexpectedEOF - } - } - if tok.tokTyp.EndToken() == tokenError { - return textError(tok, "Expecting a '<' or '{'; instead got %q", tok.txt) - } - - // TODO: use mf.NewMessage and, if not a dynamic message, use proto.UnmarshalText to unmarshal it - g := m.mf.NewDynamicMessage(extendedAnyType) - if err := g.unmarshalText(tr, tok.tokTyp.EndToken()); err != nil { - return err - } - // now we marshal the message to bytes and store in the Any - b, err := g.Marshal() - if err != nil { - return err - } - // field 2 is "value" - anyValueField := m.md.FindFieldByNumber(2) - if err := m.TrySetField(anyValueField, b); err != nil { - return err - } - - } else if (fd.GetType() == descriptorpb.FieldDescriptorProto_TYPE_GROUP || - fd.GetType() == descriptorpb.FieldDescriptorProto_TYPE_MESSAGE) && - tok.tokTyp.EndToken() != tokenError { - - // TODO: use mf.NewMessage and, if not a dynamic message, use proto.UnmarshalText to unmarshal it - g := m.mf.NewDynamicMessage(fd.GetMessageType()) - if err := g.unmarshalText(tr, tok.tokTyp.EndToken()); err != nil { - return err - } - if fd.IsRepeated() { - if err := m.TryAddRepeatedField(fd, g); err != nil { - return err - } - } else { - if err := m.TrySetField(fd, g); err != nil { - return err - } - } - } else { - if tok.tokTyp != tokenColon { - return textError(tok, "Expecting a colon ':'; instead got %q", tok.txt) - } - if err := m.unmarshalFieldValueText(fd, tr); err != nil { - return err - } - } - tok = tr.peek() - if tok.tokTyp.IsSep() { - tr.next() // consume separator - } - } -} -func findMessageDescriptor(name string, fd *desc.FileDescriptor) *desc.MessageDescriptor { - md := findMessageInTransitiveDeps(name, fd, map[*desc.FileDescriptor]struct{}{}) - if md == nil { - // couldn't find it; see if we have this message linked in - md, _ = desc.LoadMessageDescriptor(name) - } - return md -} - -func findMessageInTransitiveDeps(name string, fd *desc.FileDescriptor, seen map[*desc.FileDescriptor]struct{}) *desc.MessageDescriptor { - if _, ok := seen[fd]; ok { - // already checked this file - return nil - } - seen[fd] = struct{}{} - md := fd.FindMessage(name) - if md != nil { - return md - } - // not in this file so recursively search its deps - for _, dep := range fd.GetDependencies() { - md = findMessageInTransitiveDeps(name, dep, seen) - if md != nil { - return md - } - } - // couldn't find it - return nil -} - -func textError(tok *token, format string, args ...interface{}) error { - var msg string - if tok.tokTyp == tokenError { - msg = tok.val.(error).Error() - } else { - msg = fmt.Sprintf(format, args...) - } - return fmt.Errorf("line %d, col %d: %s", tok.pos.Line, tok.pos.Column, msg) -} - -type setFunction func(*Message, *desc.FieldDescriptor, interface{}) error - -func (m *Message) unmarshalFieldValueText(fd *desc.FieldDescriptor, tr *txtReader) error { - var set setFunction - if fd.IsRepeated() { - set = (*Message).addRepeatedField - } else { - set = mergeField - } - tok := tr.peek() - if tok.tokTyp == tokenOpenBracket { - tr.next() // consume tok - for { - if err := m.unmarshalFieldElementText(fd, tr, set); err != nil { - return err - } - tok = tr.peek() - if tok.tokTyp == tokenCloseBracket { - tr.next() // consume tok - return nil - } else if tok.tokTyp.IsSep() { - tr.next() // consume separator - } - } - } - return m.unmarshalFieldElementText(fd, tr, set) -} - -func (m *Message) unmarshalFieldElementText(fd *desc.FieldDescriptor, tr *txtReader, set setFunction) error { - tok := tr.next() - if tok.tokTyp == tokenEOF { - return io.ErrUnexpectedEOF - } - - var expected string - switch fd.GetType() { - case descriptorpb.FieldDescriptorProto_TYPE_BOOL: - if tok.tokTyp == tokenIdent { - if tok.val.(string) == "true" { - return set(m, fd, true) - } else if tok.val.(string) == "false" { - return set(m, fd, false) - } - } - expected = "boolean value" - case descriptorpb.FieldDescriptorProto_TYPE_BYTES: - if tok.tokTyp == tokenString { - return set(m, fd, []byte(tok.val.(string))) - } - expected = "bytes string value" - case descriptorpb.FieldDescriptorProto_TYPE_STRING: - if tok.tokTyp == tokenString { - return set(m, fd, tok.val) - } - expected = "string value" - case descriptorpb.FieldDescriptorProto_TYPE_FLOAT: - switch tok.tokTyp { - case tokenFloat: - return set(m, fd, float32(tok.val.(float64))) - case tokenInt: - if f, err := strconv.ParseFloat(tok.val.(string), 32); err != nil { - return err - } else { - return set(m, fd, float32(f)) - } - case tokenIdent: - ident := strings.ToLower(tok.val.(string)) - if ident == "inf" { - return set(m, fd, float32(math.Inf(1))) - } else if ident == "nan" { - return set(m, fd, float32(math.NaN())) - } - case tokenMinus: - peeked := tr.peek() - if peeked.tokTyp == tokenIdent { - ident := strings.ToLower(peeked.val.(string)) - if ident == "inf" { - tr.next() // consume peeked token - return set(m, fd, float32(math.Inf(-1))) - } - } - } - expected = "float value" - case descriptorpb.FieldDescriptorProto_TYPE_DOUBLE: - switch tok.tokTyp { - case tokenFloat: - return set(m, fd, tok.val) - case tokenInt: - if f, err := strconv.ParseFloat(tok.val.(string), 64); err != nil { - return err - } else { - return set(m, fd, f) - } - case tokenIdent: - ident := strings.ToLower(tok.val.(string)) - if ident == "inf" { - return set(m, fd, math.Inf(1)) - } else if ident == "nan" { - return set(m, fd, math.NaN()) - } - case tokenMinus: - peeked := tr.peek() - if peeked.tokTyp == tokenIdent { - ident := strings.ToLower(peeked.val.(string)) - if ident == "inf" { - tr.next() // consume peeked token - return set(m, fd, math.Inf(-1)) - } - } - } - expected = "float value" - case descriptorpb.FieldDescriptorProto_TYPE_INT32, - descriptorpb.FieldDescriptorProto_TYPE_SINT32, - descriptorpb.FieldDescriptorProto_TYPE_SFIXED32: - if tok.tokTyp == tokenInt { - if i, err := strconv.ParseInt(tok.val.(string), 10, 32); err != nil { - return err - } else { - return set(m, fd, int32(i)) - } - } - expected = "int value" - case descriptorpb.FieldDescriptorProto_TYPE_INT64, - descriptorpb.FieldDescriptorProto_TYPE_SINT64, - descriptorpb.FieldDescriptorProto_TYPE_SFIXED64: - if tok.tokTyp == tokenInt { - if i, err := strconv.ParseInt(tok.val.(string), 10, 64); err != nil { - return err - } else { - return set(m, fd, i) - } - } - expected = "int value" - case descriptorpb.FieldDescriptorProto_TYPE_UINT32, - descriptorpb.FieldDescriptorProto_TYPE_FIXED32: - if tok.tokTyp == tokenInt { - if i, err := strconv.ParseUint(tok.val.(string), 10, 32); err != nil { - return err - } else { - return set(m, fd, uint32(i)) - } - } - expected = "unsigned int value" - case descriptorpb.FieldDescriptorProto_TYPE_UINT64, - descriptorpb.FieldDescriptorProto_TYPE_FIXED64: - if tok.tokTyp == tokenInt { - if i, err := strconv.ParseUint(tok.val.(string), 10, 64); err != nil { - return err - } else { - return set(m, fd, i) - } - } - expected = "unsigned int value" - case descriptorpb.FieldDescriptorProto_TYPE_ENUM: - if tok.tokTyp == tokenIdent { - // TODO: add a flag to just ignore unrecognized enum value names? - vd := fd.GetEnumType().FindValueByName(tok.val.(string)) - if vd != nil { - return set(m, fd, vd.GetNumber()) - } - } else if tok.tokTyp == tokenInt { - if i, err := strconv.ParseInt(tok.val.(string), 10, 32); err != nil { - return err - } else { - return set(m, fd, int32(i)) - } - } - expected = fmt.Sprintf("enum %s value", fd.GetEnumType().GetFullyQualifiedName()) - case descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, - descriptorpb.FieldDescriptorProto_TYPE_GROUP: - - endTok := tok.tokTyp.EndToken() - if endTok != tokenError { - dm := m.mf.NewDynamicMessage(fd.GetMessageType()) - if err := dm.unmarshalText(tr, endTok); err != nil { - return err - } - // TODO: ideally we would use mf.NewMessage and, if not a dynamic message, use - // proto package to unmarshal it. But the text parser isn't particularly amenable - // to that, so we instead convert a dynamic message to a generated one if the - // known-type registry knows about the generated type... - var ktr *KnownTypeRegistry - if m.mf != nil { - ktr = m.mf.ktr - } - pm := ktr.CreateIfKnown(fd.GetMessageType().GetFullyQualifiedName()) - if pm != nil { - if err := dm.ConvertTo(pm); err != nil { - return set(m, fd, pm) - } - } - return set(m, fd, dm) - } - expected = fmt.Sprintf("message %s value", fd.GetMessageType().GetFullyQualifiedName()) - default: - return fmt.Errorf("field %q of message %q has unrecognized type: %v", fd.GetFullyQualifiedName(), m.md.GetFullyQualifiedName(), fd.GetType()) - } - - // if we get here, token was wrong type; create error message - var article string - if strings.Contains("aieou", expected[0:1]) { - article = "an" - } else { - article = "a" - } - return textError(tok, "Expecting %s %s; got %q", article, expected, tok.txt) -} - -func unmarshalFieldNameText(tr *txtReader, tok *token) (string, error) { - if tok.tokTyp == tokenOpenBracket || tok.tokTyp == tokenOpenParen { - // extension name - var closeType tokenType - var closeChar string - if tok.tokTyp == tokenOpenBracket { - closeType = tokenCloseBracket - closeChar = "close bracket ']'" - } else { - closeType = tokenCloseParen - closeChar = "close paren ')'" - } - // must be followed by an identifier - idents := make([]string, 0, 1) - for { - tok = tr.next() - if tok.tokTyp == tokenEOF { - return "", io.ErrUnexpectedEOF - } else if tok.tokTyp != tokenIdent { - return "", textError(tok, "Expecting an identifier; instead got %q", tok.txt) - } - idents = append(idents, tok.val.(string)) - // and then close bracket/paren, or "/" to keep adding URL elements to name - tok = tr.next() - if tok.tokTyp == tokenEOF { - return "", io.ErrUnexpectedEOF - } else if tok.tokTyp == closeType { - break - } else if tok.tokTyp != tokenSlash { - return "", textError(tok, "Expecting a %s; instead got %q", closeChar, tok.txt) - } - } - return "[" + strings.Join(idents, "/") + "]", nil - } else if tok.tokTyp == tokenIdent { - // normal field name - return tok.val.(string), nil - } else { - return "", textError(tok, "Expecting an identifier or tag number; instead got %q", tok.txt) - } -} - -func skipFieldNameText(tr *txtReader) error { - tok := tr.next() - if tok.tokTyp == tokenEOF { - return io.ErrUnexpectedEOF - } else if tok.tokTyp == tokenInt || tok.tokTyp == tokenIdent { - return nil - } else { - _, err := unmarshalFieldNameText(tr, tok) - return err - } -} - -func skipFieldValueText(tr *txtReader) error { - tok := tr.peek() - if tok.tokTyp == tokenOpenBracket { - tr.next() // consume tok - for { - if err := skipFieldElementText(tr); err != nil { - return err - } - tok = tr.peek() - if tok.tokTyp == tokenCloseBracket { - tr.next() // consume tok - return nil - } else if tok.tokTyp.IsSep() { - tr.next() // consume separator - } - - } - } - return skipFieldElementText(tr) -} - -func skipFieldElementText(tr *txtReader) error { - tok := tr.next() - switch tok.tokTyp { - case tokenEOF: - return io.ErrUnexpectedEOF - case tokenInt, tokenFloat, tokenString, tokenIdent: - return nil - case tokenOpenAngle: - return skipMessageText(tr, false) - default: - return textError(tok, "Expecting an angle bracket '<' or a value; instead got %q", tok.txt) - } -} - -func skipMessageText(tr *txtReader, isGroup bool) error { - for { - tok := tr.peek() - if tok.tokTyp == tokenEOF { - return io.ErrUnexpectedEOF - } else if isGroup && tok.tokTyp == tokenCloseBrace { - return nil - } else if !isGroup && tok.tokTyp == tokenCloseAngle { - return nil - } - - // field name or tag - if err := skipFieldNameText(tr); err != nil { - return err - } - - // field value - tok = tr.next() - if tok.tokTyp == tokenEOF { - return io.ErrUnexpectedEOF - } else if tok.tokTyp == tokenOpenBrace { - if err := skipMessageText(tr, true); err != nil { - return err - } - } else if tok.tokTyp == tokenColon { - if err := skipFieldValueText(tr); err != nil { - return err - } - } else { - return textError(tok, "Expecting a colon ':' or brace '{'; instead got %q", tok.txt) - } - - tok = tr.peek() - if tok.tokTyp.IsSep() { - tr.next() // consume separator - } - } -} - -type tokenType int - -const ( - tokenError tokenType = iota - tokenEOF - tokenIdent - tokenString - tokenInt - tokenFloat - tokenColon - tokenComma - tokenSemiColon - tokenOpenBrace - tokenCloseBrace - tokenOpenBracket - tokenCloseBracket - tokenOpenAngle - tokenCloseAngle - tokenOpenParen - tokenCloseParen - tokenSlash - tokenMinus -) - -func (t tokenType) IsSep() bool { - return t == tokenComma || t == tokenSemiColon -} - -func (t tokenType) EndToken() tokenType { - switch t { - case tokenOpenAngle: - return tokenCloseAngle - case tokenOpenBrace: - return tokenCloseBrace - default: - return tokenError - } -} - -type token struct { - tokTyp tokenType - val interface{} - txt string - pos scanner.Position -} - -type txtReader struct { - scanner scanner.Scanner - peeked token - havePeeked bool -} - -func newReader(text []byte) *txtReader { - sc := scanner.Scanner{} - sc.Init(bytes.NewReader(text)) - sc.Mode = scanner.ScanIdents | scanner.ScanInts | scanner.ScanFloats | scanner.ScanChars | - scanner.ScanStrings | scanner.ScanComments | scanner.SkipComments - // identifiers are same restrictions as Go identifiers, except we also allow dots since - // we accept fully-qualified names - sc.IsIdentRune = func(ch rune, i int) bool { - return ch == '_' || unicode.IsLetter(ch) || - (i > 0 && unicode.IsDigit(ch)) || - (i > 0 && ch == '.') - } - // ignore errors; we handle them if/when we see malformed tokens - sc.Error = func(s *scanner.Scanner, msg string) {} - return &txtReader{scanner: sc} -} - -func (p *txtReader) peek() *token { - if p.havePeeked { - return &p.peeked - } - t := p.scanner.Scan() - if t == scanner.EOF { - p.peeked.tokTyp = tokenEOF - p.peeked.val = nil - p.peeked.txt = "" - p.peeked.pos = p.scanner.Position - } else if err := p.processToken(t, p.scanner.TokenText(), p.scanner.Position); err != nil { - p.peeked.tokTyp = tokenError - p.peeked.val = err - } - p.havePeeked = true - return &p.peeked -} - -func (p *txtReader) processToken(t rune, text string, pos scanner.Position) error { - p.peeked.pos = pos - p.peeked.txt = text - switch t { - case scanner.Ident: - p.peeked.tokTyp = tokenIdent - p.peeked.val = text - case scanner.Int: - p.peeked.tokTyp = tokenInt - p.peeked.val = text // can't parse the number because we don't know if it's signed or unsigned - case scanner.Float: - p.peeked.tokTyp = tokenFloat - var err error - if p.peeked.val, err = strconv.ParseFloat(text, 64); err != nil { - return err - } - case scanner.Char, scanner.String: - p.peeked.tokTyp = tokenString - var err error - if p.peeked.val, err = strconv.Unquote(text); err != nil { - return err - } - case '-': // unary minus, for negative ints and floats - ch := p.scanner.Peek() - if ch < '0' || ch > '9' { - p.peeked.tokTyp = tokenMinus - p.peeked.val = '-' - } else { - t := p.scanner.Scan() - if t == scanner.EOF { - return io.ErrUnexpectedEOF - } else if t == scanner.Float { - p.peeked.tokTyp = tokenFloat - text += p.scanner.TokenText() - p.peeked.txt = text - var err error - if p.peeked.val, err = strconv.ParseFloat(text, 64); err != nil { - p.peeked.pos = p.scanner.Position - return err - } - } else if t == scanner.Int { - p.peeked.tokTyp = tokenInt - text += p.scanner.TokenText() - p.peeked.txt = text - p.peeked.val = text // can't parse the number because we don't know if it's signed or unsigned - } else { - p.peeked.pos = p.scanner.Position - return fmt.Errorf("expecting an int or float but got %q", p.scanner.TokenText()) - } - } - case ':': - p.peeked.tokTyp = tokenColon - p.peeked.val = ':' - case ',': - p.peeked.tokTyp = tokenComma - p.peeked.val = ',' - case ';': - p.peeked.tokTyp = tokenSemiColon - p.peeked.val = ';' - case '{': - p.peeked.tokTyp = tokenOpenBrace - p.peeked.val = '{' - case '}': - p.peeked.tokTyp = tokenCloseBrace - p.peeked.val = '}' - case '<': - p.peeked.tokTyp = tokenOpenAngle - p.peeked.val = '<' - case '>': - p.peeked.tokTyp = tokenCloseAngle - p.peeked.val = '>' - case '[': - p.peeked.tokTyp = tokenOpenBracket - p.peeked.val = '[' - case ']': - p.peeked.tokTyp = tokenCloseBracket - p.peeked.val = ']' - case '(': - p.peeked.tokTyp = tokenOpenParen - p.peeked.val = '(' - case ')': - p.peeked.tokTyp = tokenCloseParen - p.peeked.val = ')' - case '/': - // only allowed to separate URL components in expanded Any format - p.peeked.tokTyp = tokenSlash - p.peeked.val = '/' - default: - return fmt.Errorf("invalid character: %c", t) - } - return nil -} - -func (p *txtReader) next() *token { - t := p.peek() - if t.tokTyp != tokenEOF && t.tokTyp != tokenError { - p.havePeeked = false - } - return t -} diff --git a/vendor/github.com/jhump/protoreflect/internal/codec/buffer.go b/vendor/github.com/jhump/protoreflect/internal/codec/buffer.go deleted file mode 100644 index 09f8849e..00000000 --- a/vendor/github.com/jhump/protoreflect/internal/codec/buffer.go +++ /dev/null @@ -1,118 +0,0 @@ -package codec - -import ( - "fmt" - "io" -) - -// Buffer is a reader and a writer that wraps a slice of bytes and also -// provides API for decoding and encoding the protobuf binary format. -// -// Its operation is similar to that of a bytes.Buffer: writing pushes -// data to the end of the buffer while reading pops data from the head -// of the buffer. So the same buffer can be used to both read and write. -type Buffer struct { - buf []byte - index int - - // tmp is used when another byte slice is needed, such as when - // serializing messages, since we need to know the length before - // we can write the length prefix; by caching this, including - // after it is grown by serialization operations, we reduce the - // number of allocations needed - tmp []byte - - deterministic bool -} - -// NewBuffer creates a new buffer with the given slice of bytes as the -// buffer's initial contents. -func NewBuffer(buf []byte) *Buffer { - return &Buffer{buf: buf} -} - -// SetDeterministic sets this buffer to encode messages deterministically. This -// is useful for tests. But the overhead is non-zero, so it should not likely be -// used outside of tests. When true, map fields in a message must have their -// keys sorted before serialization to ensure deterministic output. Otherwise, -// values in a map field will be serialized in map iteration order. -func (cb *Buffer) SetDeterministic(deterministic bool) { - cb.deterministic = deterministic -} - -// IsDeterministic returns whether or not this buffer is configured to encode -// messages deterministically. -func (cb *Buffer) IsDeterministic() bool { - return cb.deterministic -} - -// Reset resets this buffer back to empty. Any subsequent writes/encodes -// to the buffer will allocate a new backing slice of bytes. -func (cb *Buffer) Reset() { - cb.buf = []byte(nil) - cb.index = 0 -} - -// Bytes returns the slice of bytes remaining in the buffer. Note that -// this does not perform a copy: if the contents of the returned slice -// are modified, the modifications will be visible to subsequent reads -// via the buffer. -func (cb *Buffer) Bytes() []byte { - return cb.buf[cb.index:] -} - -// String returns the remaining bytes in the buffer as a string. -func (cb *Buffer) String() string { - return string(cb.Bytes()) -} - -// EOF returns true if there are no more bytes remaining to read. -func (cb *Buffer) EOF() bool { - return cb.index >= len(cb.buf) -} - -// Skip attempts to skip the given number of bytes in the input. If -// the input has fewer bytes than the given count, io.ErrUnexpectedEOF -// is returned and the buffer is unchanged. Otherwise, the given number -// of bytes are skipped and nil is returned. -func (cb *Buffer) Skip(count int) error { - if count < 0 { - return fmt.Errorf("proto: bad byte length %d", count) - } - newIndex := cb.index + count - if newIndex < cb.index || newIndex > len(cb.buf) { - return io.ErrUnexpectedEOF - } - cb.index = newIndex - return nil -} - -// Len returns the remaining number of bytes in the buffer. -func (cb *Buffer) Len() int { - return len(cb.buf) - cb.index -} - -// Read implements the io.Reader interface. If there are no bytes -// remaining in the buffer, it will return 0, io.EOF. Otherwise, -// it reads max(len(dest), cb.Len()) bytes from input and copies -// them into dest. It returns the number of bytes copied and a nil -// error in this case. -func (cb *Buffer) Read(dest []byte) (int, error) { - if cb.index == len(cb.buf) { - return 0, io.EOF - } - copied := copy(dest, cb.buf[cb.index:]) - cb.index += copied - return copied, nil -} - -var _ io.Reader = (*Buffer)(nil) - -// Write implements the io.Writer interface. It always returns -// len(data), nil. -func (cb *Buffer) Write(data []byte) (int, error) { - cb.buf = append(cb.buf, data...) - return len(data), nil -} - -var _ io.Writer = (*Buffer)(nil) diff --git a/vendor/github.com/jhump/protoreflect/internal/codec/decode.go b/vendor/github.com/jhump/protoreflect/internal/codec/decode.go deleted file mode 100644 index a25f680f..00000000 --- a/vendor/github.com/jhump/protoreflect/internal/codec/decode.go +++ /dev/null @@ -1,346 +0,0 @@ -package codec - -import ( - "errors" - "fmt" - "io" - "math" - - "github.com/golang/protobuf/proto" -) - -// ErrOverflow is returned when an integer is too large to be represented. -var ErrOverflow = errors.New("proto: integer overflow") - -// ErrBadWireType is returned when decoding a wire-type from a buffer that -// is not valid. -var ErrBadWireType = errors.New("proto: bad wiretype") - -func (cb *Buffer) decodeVarintSlow() (x uint64, err error) { - i := cb.index - l := len(cb.buf) - - for shift := uint(0); shift < 64; shift += 7 { - if i >= l { - err = io.ErrUnexpectedEOF - return - } - b := cb.buf[i] - i++ - x |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - cb.index = i - return - } - } - - // The number is too large to represent in a 64-bit value. - err = ErrOverflow - return -} - -// DecodeVarint reads a varint-encoded integer from the Buffer. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func (cb *Buffer) DecodeVarint() (uint64, error) { - i := cb.index - buf := cb.buf - - if i >= len(buf) { - return 0, io.ErrUnexpectedEOF - } else if buf[i] < 0x80 { - cb.index++ - return uint64(buf[i]), nil - } else if len(buf)-i < 10 { - return cb.decodeVarintSlow() - } - - var b uint64 - // we already checked the first byte - x := uint64(buf[i]) - 0x80 - i++ - - b = uint64(buf[i]) - i++ - x += b << 7 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 7 - - b = uint64(buf[i]) - i++ - x += b << 14 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 14 - - b = uint64(buf[i]) - i++ - x += b << 21 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 21 - - b = uint64(buf[i]) - i++ - x += b << 28 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 28 - - b = uint64(buf[i]) - i++ - x += b << 35 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 35 - - b = uint64(buf[i]) - i++ - x += b << 42 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 42 - - b = uint64(buf[i]) - i++ - x += b << 49 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 49 - - b = uint64(buf[i]) - i++ - x += b << 56 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 56 - - b = uint64(buf[i]) - i++ - x += b << 63 - if b&0x80 == 0 { - goto done - } - // x -= 0x80 << 63 // Always zero. - - return 0, ErrOverflow - -done: - cb.index = i - return x, nil -} - -// DecodeTagAndWireType decodes a field tag and wire type from input. -// This reads a varint and then extracts the two fields from the varint -// value read. -func (cb *Buffer) DecodeTagAndWireType() (tag int32, wireType int8, err error) { - var v uint64 - v, err = cb.DecodeVarint() - if err != nil { - return - } - // low 7 bits is wire type - wireType = int8(v & 7) - // rest is int32 tag number - v = v >> 3 - if v > math.MaxInt32 { - err = fmt.Errorf("tag number out of range: %d", v) - return - } - tag = int32(v) - return -} - -// DecodeFixed64 reads a 64-bit integer from the Buffer. -// This is the format for the -// fixed64, sfixed64, and double protocol buffer types. -func (cb *Buffer) DecodeFixed64() (x uint64, err error) { - // x, err already 0 - i := cb.index + 8 - if i < 0 || i > len(cb.buf) { - err = io.ErrUnexpectedEOF - return - } - cb.index = i - - x = uint64(cb.buf[i-8]) - x |= uint64(cb.buf[i-7]) << 8 - x |= uint64(cb.buf[i-6]) << 16 - x |= uint64(cb.buf[i-5]) << 24 - x |= uint64(cb.buf[i-4]) << 32 - x |= uint64(cb.buf[i-3]) << 40 - x |= uint64(cb.buf[i-2]) << 48 - x |= uint64(cb.buf[i-1]) << 56 - return -} - -// DecodeFixed32 reads a 32-bit integer from the Buffer. -// This is the format for the -// fixed32, sfixed32, and float protocol buffer types. -func (cb *Buffer) DecodeFixed32() (x uint64, err error) { - // x, err already 0 - i := cb.index + 4 - if i < 0 || i > len(cb.buf) { - err = io.ErrUnexpectedEOF - return - } - cb.index = i - - x = uint64(cb.buf[i-4]) - x |= uint64(cb.buf[i-3]) << 8 - x |= uint64(cb.buf[i-2]) << 16 - x |= uint64(cb.buf[i-1]) << 24 - return -} - -// DecodeRawBytes reads a count-delimited byte buffer from the Buffer. -// This is the format used for the bytes protocol buffer -// type and for embedded messages. -func (cb *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) { - n, err := cb.DecodeVarint() - if err != nil { - return nil, err - } - - nb := int(n) - if nb < 0 { - return nil, fmt.Errorf("proto: bad byte length %d", nb) - } - end := cb.index + nb - if end < cb.index || end > len(cb.buf) { - return nil, io.ErrUnexpectedEOF - } - - if !alloc { - buf = cb.buf[cb.index:end] - cb.index = end - return - } - - buf = make([]byte, nb) - copy(buf, cb.buf[cb.index:]) - cb.index = end - return -} - -// ReadGroup reads the input until a "group end" tag is found -// and returns the data up to that point. Subsequent reads from -// the buffer will read data after the group end tag. If alloc -// is true, the data is copied to a new slice before being returned. -// Otherwise, the returned slice is a view into the buffer's -// underlying byte slice. -// -// This function correctly handles nested groups: if a "group start" -// tag is found, then that group's end tag will be included in the -// returned data. -func (cb *Buffer) ReadGroup(alloc bool) ([]byte, error) { - var groupEnd, dataEnd int - groupEnd, dataEnd, err := cb.findGroupEnd() - if err != nil { - return nil, err - } - var results []byte - if !alloc { - results = cb.buf[cb.index:dataEnd] - } else { - results = make([]byte, dataEnd-cb.index) - copy(results, cb.buf[cb.index:]) - } - cb.index = groupEnd - return results, nil -} - -// SkipGroup is like ReadGroup, except that it discards the -// data and just advances the buffer to point to the input -// right *after* the "group end" tag. -func (cb *Buffer) SkipGroup() error { - groupEnd, _, err := cb.findGroupEnd() - if err != nil { - return err - } - cb.index = groupEnd - return nil -} - -// SkipField attempts to skip the value of a field with the given wire -// type. When consuming a protobuf-encoded stream, it can be called immediately -// after DecodeTagAndWireType to discard the subsequent data for the field. -func (cb *Buffer) SkipField(wireType int8) error { - switch wireType { - case proto.WireFixed32: - if err := cb.Skip(4); err != nil { - return err - } - case proto.WireFixed64: - if err := cb.Skip(8); err != nil { - return err - } - case proto.WireVarint: - // skip varint by finding last byte (has high bit unset) - i := cb.index - limit := i + 10 // varint cannot be >10 bytes - for { - if i >= limit { - return ErrOverflow - } - if i >= len(cb.buf) { - return io.ErrUnexpectedEOF - } - if cb.buf[i]&0x80 == 0 { - break - } - i++ - } - // TODO: This would only overflow if buffer length was MaxInt and we - // read the last byte. This is not a real/feasible concern on 64-bit - // systems. Something to worry about for 32-bit systems? Do we care? - cb.index = i + 1 - case proto.WireBytes: - l, err := cb.DecodeVarint() - if err != nil { - return err - } - if err := cb.Skip(int(l)); err != nil { - return err - } - case proto.WireStartGroup: - if err := cb.SkipGroup(); err != nil { - return err - } - default: - return ErrBadWireType - } - return nil -} - -func (cb *Buffer) findGroupEnd() (groupEnd int, dataEnd int, err error) { - start := cb.index - defer func() { - cb.index = start - }() - for { - fieldStart := cb.index - // read a field tag - _, wireType, err := cb.DecodeTagAndWireType() - if err != nil { - return 0, 0, err - } - if wireType == proto.WireEndGroup { - return cb.index, fieldStart, nil - } - // skip past the field's data - if err := cb.SkipField(wireType); err != nil { - return 0, 0, err - } - } -} diff --git a/vendor/github.com/jhump/protoreflect/internal/codec/encode.go b/vendor/github.com/jhump/protoreflect/internal/codec/encode.go deleted file mode 100644 index 524f1bcb..00000000 --- a/vendor/github.com/jhump/protoreflect/internal/codec/encode.go +++ /dev/null @@ -1,147 +0,0 @@ -package codec - -import ( - "github.com/golang/protobuf/proto" -) - -// EncodeVarint writes a varint-encoded integer to the Buffer. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func (cb *Buffer) EncodeVarint(x uint64) error { - for x >= 1<<7 { - cb.buf = append(cb.buf, uint8(x&0x7f|0x80)) - x >>= 7 - } - cb.buf = append(cb.buf, uint8(x)) - return nil -} - -// EncodeTagAndWireType encodes the given field tag and wire type to the -// buffer. This combines the two values and then writes them as a varint. -func (cb *Buffer) EncodeTagAndWireType(tag int32, wireType int8) error { - v := uint64((int64(tag) << 3) | int64(wireType)) - return cb.EncodeVarint(v) -} - -// EncodeFixed64 writes a 64-bit integer to the Buffer. -// This is the format for the -// fixed64, sfixed64, and double protocol buffer types. -func (cb *Buffer) EncodeFixed64(x uint64) error { - cb.buf = append(cb.buf, - uint8(x), - uint8(x>>8), - uint8(x>>16), - uint8(x>>24), - uint8(x>>32), - uint8(x>>40), - uint8(x>>48), - uint8(x>>56)) - return nil -} - -// EncodeFixed32 writes a 32-bit integer to the Buffer. -// This is the format for the -// fixed32, sfixed32, and float protocol buffer types. -func (cb *Buffer) EncodeFixed32(x uint64) error { - cb.buf = append(cb.buf, - uint8(x), - uint8(x>>8), - uint8(x>>16), - uint8(x>>24)) - return nil -} - -// EncodeRawBytes writes a count-delimited byte buffer to the Buffer. -// This is the format used for the bytes protocol buffer -// type and for embedded messages. -func (cb *Buffer) EncodeRawBytes(b []byte) error { - if err := cb.EncodeVarint(uint64(len(b))); err != nil { - return err - } - cb.buf = append(cb.buf, b...) - return nil -} - -// EncodeMessage writes the given message to the buffer. -func (cb *Buffer) EncodeMessage(pm proto.Message) error { - bytes, err := marshalMessage(cb.buf, pm, cb.deterministic) - if err != nil { - return err - } - cb.buf = bytes - return nil -} - -// EncodeDelimitedMessage writes the given message to the buffer with a -// varint-encoded length prefix (the delimiter). -func (cb *Buffer) EncodeDelimitedMessage(pm proto.Message) error { - bytes, err := marshalMessage(cb.tmp, pm, cb.deterministic) - if err != nil { - return err - } - // save truncated buffer if it was grown (so we can re-use it and - // curtail future allocations) - if cap(bytes) > cap(cb.tmp) { - cb.tmp = bytes[:0] - } - return cb.EncodeRawBytes(bytes) -} - -func marshalMessage(b []byte, pm proto.Message, deterministic bool) ([]byte, error) { - // We try to use the most efficient way to marshal to existing slice. - - if deterministic { - // see if the message has custom deterministic methods, preferring an - // "append" method over one that must always re-allocate - madm, ok := pm.(interface { - MarshalAppendDeterministic(b []byte) ([]byte, error) - }) - if ok { - return madm.MarshalAppendDeterministic(b) - } - - mdm, ok := pm.(interface { - MarshalDeterministic() ([]byte, error) - }) - if ok { - bytes, err := mdm.MarshalDeterministic() - if err != nil { - return nil, err - } - if len(b) == 0 { - return bytes, nil - } - return append(b, bytes...), nil - } - - var buf proto.Buffer - buf.SetDeterministic(true) - if err := buf.Marshal(pm); err != nil { - return nil, err - } - bytes := buf.Bytes() - if len(b) == 0 { - return bytes, nil - } - return append(b, bytes...), nil - } - - mam, ok := pm.(interface { - // see if we can append the message, vs. having to re-allocate - MarshalAppend(b []byte) ([]byte, error) - }) - if ok { - return mam.MarshalAppend(b) - } - - // lowest common denominator - bytes, err := proto.Marshal(pm) - if err != nil { - return nil, err - } - if len(b) == 0 { - return bytes, nil - } - return append(b, bytes...), nil -} diff --git a/vendor/modules.txt b/vendor/modules.txt index dfb3c3d7..02418d37 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,5 +1,5 @@ -# gioui.org v0.6.0 -## explicit; go 1.19 +# gioui.org v0.7.0 +## explicit; go 1.21 gioui.org/app gioui.org/app/internal/windows gioui.org/app/internal/xkb @@ -51,8 +51,8 @@ gioui.org/cpu gioui.org/shader gioui.org/shader/gio gioui.org/shader/piet -# gioui.org/x v0.6.1 -## explicit; go 1.18 +# gioui.org/x v0.7.0 +## explicit; go 1.21 gioui.org/x/component gioui.org/x/explorer gioui.org/x/outlay @@ -104,23 +104,19 @@ github.com/go-text/typesetting/unicodedata github.com/godbus/dbus/v5 # github.com/golang/protobuf v1.5.4 ## explicit; go 1.17 -github.com/golang/protobuf/jsonpb github.com/golang/protobuf/proto # github.com/google/uuid v1.6.0 ## explicit github.com/google/uuid # github.com/jhump/protoreflect v1.16.0 ## explicit; go 1.19 -github.com/jhump/protoreflect/codec github.com/jhump/protoreflect/desc github.com/jhump/protoreflect/desc/internal github.com/jhump/protoreflect/desc/protoparse github.com/jhump/protoreflect/desc/protoparse/ast github.com/jhump/protoreflect/desc/sourceinfo -github.com/jhump/protoreflect/dynamic github.com/jhump/protoreflect/grpcreflect github.com/jhump/protoreflect/internal -github.com/jhump/protoreflect/internal/codec # github.com/shopspring/decimal v1.3.1 ## explicit; go 1.13 github.com/shopspring/decimal